有没有办法使用这样的东西:
private const int MaxTextLength = "Text i want to use".Length;
Run Code Online (Sandbox Code Playgroud)
我认为它比使用类似的东西更具可读性且更不容易出错:
private const int MaxTextLength = 18;
Run Code Online (Sandbox Code Playgroud)
有没有办法让文本的长度成为常量变量的来源?
我一直想知道为什么C#不支持const类或方法级别.我知道Jon Skeet长期以来一直希望支持不变性,并且我认为使用函数const的C++语法可以帮助实现这一点.通过在类级别添加const关键字,我们将获得全面支持.
现在,我的问题是,C#团队没有开发出这种支持的原因是什么?
我想可以通过编译时检查或通过属性创建所有内容,而无需更改CLR.我不介意代码能够通过反射覆盖const行为.
想象一下:
const class NumberContainer
{
public int Number { get; }
}
Run Code Online (Sandbox Code Playgroud)
..这样的类只能在构造时填充,所以我们需要一个构造函数来接受一个int.
另一个例子是方法级别的const:
public int AddNumbers(NumberContainer n1, NumberContainer n2) const
{
return n1.Number + n2.Number;
}
Run Code Online (Sandbox Code Playgroud)
const级方法不应该能够改变它们自己的类中的状态或传递给它们的引用类型的实例.此外,const级函数只能在其范围内调用其他const级函数.
我不确定lambdas和代表是否会使一切都太难(或不可能)实现,但我确信有更多语言和编译器设计经验的人可以告诉我.
正如史蒂夫B在评论中指出的那样,存在readonly使得事情变得更复杂,因为const和readonly它们在期间接近相同runtime,但是readonly在编译期间无法确定值.我想我们可以拥有const和readonly水平,但这可能太混乱了?
那么,没有实现这个的原因是什么?可用性问题(理解C++中的常量通常对新用户来说很难),语言设计问题(无法完成)或仅仅是优先级问题(不变性的时代 - 嗡嗡声已经结束).
可能重复:
我应该返回const对象吗?
(该问题的原始标题是:int foo()或const int foo()?解释为什么我错过了它.)
有效的C++,第3项:尽可能使用const.特别是,返回const对象被提升以避免意外的赋值if (a*b = c) {.我发现它有点偏执,但我一直在遵循这个建议.
在我看来,返回const对象会降低C++ 11中的性能.
#include <iostream>
using namespace std;
class C {
public:
C() : v(nullptr) { }
C& operator=(const C& other) {
cout << "copy" << endl;
// copy contents of v[]
return *this;
}
C& operator=(C&& other) {
cout << "move" << endl;
v = other.v, other.v = nullptr;
return *this;
}
private:
int* v;
};
const C const_is_returned() { return C(); }
C nonconst_is_returned() …Run Code Online (Sandbox Code Playgroud) 以下代码在MSVC2010上编译并运行,是吗?
const std::string s = "foo";
std::string s2(std::move(s));
Run Code Online (Sandbox Code Playgroud)
我可以看出为什么这可能不会破坏任何东西,因为如果我采用s的内部我必须知道没有人会使用它所以我不得不放弃const.然而,编译器在ROM(在嵌入式应用程序中)实现const对象的位置呢?那么此举会变成副本吗?或者MSVC应该给我一个错误?
我需要实现对私有成员容器的只读访问.如果我返回一个常量引用,是否可以const_cast它并获得对该成员的完全访问权限?使用的技术是什么?
谢谢.
对于C++新手来说,允许const成员函数在类引用的对象(通过指针或引用)上调用非const方法通常会让人感到困惑.例如,以下内容完全正确:
class SomeClass
{
class SomeClassImpl;
SomeClassImpl * impl_; // PImpl idiom
public:
void const_method() const;
};
struct SomeClass::SomeClassImpl
{
void non_const_method() { /*modify data*/ }
};
void SomeClass::const_method() const
{
impl_->non_const_method(); //ok because impl_ is const, not *impl_
};
Run Code Online (Sandbox Code Playgroud)
但是,如果constness传播到尖头对象,它有时会非常方便(我自愿使用PImpl习语,因为它是我认为"constness传播"非常有用的情况之一).
使用指针时,可以通过使用某种智能指针轻松实现这一点,操作符在constness上重载:
template < typename T >
class const_propagating_ptr
{
public:
const_propagating_ptr( T * ptr ) : ptr_( ptr ) {}
T & operator*() { return *ptr_; }
T const & operator*() const { return *ptr_; }
T * operator->() …Run Code Online (Sandbox Code Playgroud) 我知道,在C你不能隐式转换,例如,char**以const char**(CF C-有问必答,SO问题1,SO问题2).
另一方面,如果我看到一个声明如此的函数:
void foo(char** ppData);
Run Code Online (Sandbox Code Playgroud)
我必须假设该函数可能会更改传入的数据.因此,如果我正在编写一个不会更改数据的函数,我认为最好声明:
void foo(const char** ppData);
Run Code Online (Sandbox Code Playgroud)
甚至:
void foo(const char * const * ppData);
Run Code Online (Sandbox Code Playgroud)
但这使得该功能的用户处于尴尬的境地.他们可能有:
int main(int argc, char** argv)
{
foo(argv); // Oh no, compiler error (or warning)
...
}
Run Code Online (Sandbox Code Playgroud)
为了干净地调用我的函数,他们需要插入一个演员.
我来自一个主要是C++的背景,由于C++更深入的const规则,这不是一个问题.
C中惯用的解决方案是什么?
声明foo为a char**,并且只记录它不会改变其输入的事实?这看起来有点严重,尤其是 因为它惩罚那些可能const char**想要传递它的用户(现在他们必须抛弃常量)
强制用户投射他们的输入,增加常量.
别的什么?
在接口中定义函数时:
virtual void ModifyPreComputedCoeffs ( std::vector < IndexCoeffPair_t > & model_ ) = 0;
Run Code Online (Sandbox Code Playgroud)
我们想要指定不应该在push_back等意义上改变向量model_操作不应该对向量进行操作,但是可以更改model_中的IndexCoeffPair_t结构对象.我们该如何指定?
virtual void ModifyPreComputedCoeffs ( const std::vector < IndexCoeffPair_t > & model_ ) = 0;
Run Code Online (Sandbox Code Playgroud)
我觉得不行.
#include <type_traits>
struct foo;
int main()
{
const foo *bar;
static_assert(std::is_const<decltype(*bar)>::value,
"expected const but this is non-const!");
}
Run Code Online (Sandbox Code Playgroud)
这导致static_assert意外失败.这有点类似于关于const引用的这个问题但不完全相同.
在我的情况下,解除引用bar应该给出一个const foo类型的实例,但是std::is_const却说不然.
有两个const类型会发出警告/错误.但是,如果已定义类型typedef,则编译器接受它(Visual Studio 2013和在线编译器C++ shell).
#include <iostream>
typedef const int value_type;
int main()
{
const value_type n = 0; //ok
const const int n2 = 0; //error C4114
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有没有人知道为什么?它是一个const (const int),不同于const const int?