C基础之const用法
int i = -1;
const int ic = i;
const int *pic = ⁣
// int *const cpi = ⁣// compile error
// cannot initialize a variable of type 'int *const'
// with an rvalue of type 'const int *'
int main()
{
return 0;
}
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
char *str5 = "abc";
char *str6 = "abc";
const char *str7 = "abc";
const char *str8 = "abc";
int main()
{
printf("%p %p\n", str1, str2);
printf("%p %p\n", str3, str4);
printf("%p %p\n", str5, str6);
printf("%p %p\n", str7, str8);
str1[0] = '0';
// str3[0] = '0'; // compile error
// Cannot assign to variable 'str3' with const-qualified type 'const char [4]'
// str5[0] = '0'; // run error: const area cannot be modified
// str7[0] = '0'; //compile error
// Read-only variable is not assignable
cout << (str1 == str2) << endl;
cout << (str3 == str4) << endl;
cout << (str5 == str6) << endl;
cout << (str7 == str8) << endl;
}
输出为:
0047B038 0047B03C
004795F8 004795FC
00479600 00479604
00479608 0047960C
0
0
0
0
如果为char [],会分配空间,
如果char*,指定的常量区,不可修改。如果是const char* ,从编译上就能控制不可修改。char*需要运行时才能识别。
class A
{
public:
static int a;
// static int a = 1; // ERROR
// Non-const static data member must be initialized out pf line
};
int A::a = 1;
int main()
{
cout << A::a << endl;
}
这种方案可以,
class A声明放在classA.h中,int A::a = 1; 放在classA.cpp和main.cpp中都可以。
但是放在classA.h中不可以,因为public: static int A::a" (?a@A@@2HA) 已经在 main.cpp.obj 中定义
class A
{
public:
static const int a = 1;
};
这就是没问题的,这是因为编译器知道静态常量成员的值不会变,因此会在编译阶段优化掉,比如将所有a出现的地方都替换成1之类的。这样使得a不会***store in memory***,从而没有违反上述规则。
class A {
public:
// 非非 非常 静非 静常
int a = 1;
const int b = 2;
//const int b{2}; // another initialization method
static int c;
static const int d;
static const int e = 5;
};
int A::c = 3;
// int A::c{3}; // another initialization method
const int A::d = 4;
int main() {
cout << &A::a << " " << &A::b << " " << &A::c << " " << &A::d << " " << &A::e << endl;
A a1;
A a2;
cout << &a1.a << " " << &a1.b << " " << &a1.c << " " << &a1.d << " " << &a1.e << endl;
cout << &a2.a << " " << &a2.b << " " << &a2.c << " " << &a2.d << " " << &a2.e << endl;
return 0;
}
程序输出为:
1 1 0004B000 00048B30 00048B6C
012FF8B0 012FF8B4 0004B000 00048B30 00048B6C
012FF8A0 012FF8A4 0004B000 00048B30 00048B6C
说明静态成员地址都一样,非静态成员地址都不一样。就算是在类内声明处赋值,地址也是一样的,应该是被优化了。
有一种说法是对e取地址则报错说找不到这个成员,这进一步说明成员e被优化掉了。自己实测是没有被优化。
class A
{
public:
static int a;
};
int A::a = 1; // 正确
static int A::a = 1; // confusing and illegal, is it static LINKAGE
// or static STORAGE DURATION
// or static MEMBERSHIP?
另外在上述代码我们可以发现,如果是在类外初始化静态成员,则不用再加static,因为一般语义下的static是C语言中的**“静态”,”静态成员“**这一语义是C++独有的且只在类内部生效
参考资料
https://blog.csdn.net/bloodfeast/article/details/99759527
1. 类的静态成员变量的声明原则:
在.H文件中,用static 关键字进行前缀修饰即可,不可以直接进行初始化,基础变量除外。
如果要初始化自定义的类型,则需要在CPP文件中进行初始化
static CPerson* Police;
https://www.cnblogs.com/icmzn/p/5668862.html
class A
{
public:
// 非非 非常 静非 静常
int a = 1;
const int b = 2;
static int c = 3; // compile error
// Non-const static data member must be initialized out of line
static const int d = 4;
};
静非c禁止在类内声明处赋值。静常可以在类内声明处赋值,因为属于常量,不同对象的指向同一个地方。
class A
{
public:
// 非非 非常 静非 静常
int a;
const int b;
static int c;
static const int d;
};
int A::a = 1; // compile error
// None-static data member defined out-of-line
const int A::b = 2; // compile error
// None-static data member defined out-of-line
int A::c = 3; // compile ok
const int A::d = 4;
非静态成员禁止在类外实现处赋值。
class A
{
public:
// 非非 非常 静非 静常
int a;
const int b;
static int c;
static const int d;
A() : a(1), b(2), c(3), d(4) { } // compile error
// Member initializer 'c' does not name a non-static data member or base class
// Member initializer 'd' does not name a non-static data member or base class
};
如果非常b没有在声明时赋值,则必须在处理化列表时候赋值,不然编译出错。
静非c和静常d禁止在初始化列表时赋值,因为静态变量不属于对象。
class A
{
public:
// 非非 非常 静非 静常
int a;
const int b = 2;
static int c;
static const int d;
A(int i) {
a = 1;
//b = 2; // compile error
//Cannot assign to non-static data member 'b' with const-qualified type 'const int'
c = i;
//d = 4; // compile error
//Cannot assign to variable 'd' with const-qualified type 'const int'
}
};
int A::c = 3;
const int A::d = 4;
int main() {
A a1(10);
A a2(20);
cout << a1.a << " " << a1.b << " " << a1.c << " " << a1.d << endl;
cout << a2.a << " " << a2.b << " " << a2.c << " " << a2.d << endl;
return 0;
}
输出为:
1 2 20 4
1 2 20 4
常量成员禁止在构造函数中赋值。
类型 初始化方式 |
类内声明 |
类外实现 |
初始化列表 |
构造函数 |
非非 |
Y |
N |
Y |
Y |
非常
|
Y |
N |
Y |
N |
静非 |
N |
Y |
N |
Y |
静常 |
Y |
Y |
N |
N |
总结:
类内声明:静非不行;
类外实现:不是静态不行;
初始化列表:静态不行;
构造函数:常量不行。