class A{
public:
int id;
static A getA() {
return self;
}
private:
static A self;
A(){
id = 3;
std::cout << "A" << " ";
}
};
代码如上, 类似这样的类, 我要如何初始化self呢?
同时我发现, 我如果这样写的话, 它会默认调用可以初始化A()初始化self, 屏幕上能显示 A第一行3
, 但是如果我在头文件中倒数第二行 A::self
改成 A::self();
就报错, 说我重定义了self, 他说之前self是一个属性, 这里我重定义它为一个函数...
#include <iostream>
#include "A.h"
using namespace std;
int main(void){
cout << "第一行";
cout << A::self.x;
}
#ifndef LAB_A_H
#define LAB_A_H
#include <iostream>
class A{
public:
int x = 3;
static A self;
private:
A(){
std::cout << "A";
}
};
A A::self;
#endif //LAB_A_H
问题在于 :
对于这种成员的初始化, 如果使用默认的构造函数就不能加括号是吗?(我尝试过用一个带参数的构造函数, 是可以编译运行的)
如果我去掉最后一行, 也就是不对这个静态属性self进行初始化, 只要我main.cpp中不用到这个类, 我就算include这个头文件(显然是错误的), 也可以正常运行, 这又是为什么呢?
黄舟2017-04-17 13:57:00
If you can change this class, then the standard approach is
static A& getA() {
static A a;
return a;
}
a will only be initialized once, when getA is called for the first time. This is thread-safe since C++11.
If you can't change it, then you can only initialize this self outside the class. And your constructor is private, so it cannot be initialized.
Regarding your default constructor without ():
Yes, parentheses will cause ambiguity, and the compiler will understand that this is a function signature
A a(); // 声明一个返回值为A,不含参数的函数
黄舟2017-04-17 13:57:00
Just write this in a.cpp:
// a.cpp
#include "a.h"
A A::self;
Tested it:
// main.cpp
#include "a.h"
int main() {
A a = A::getA();
std::cout << "| static A.id:" << a.id << std::endl;
return 0;
}
// output:
A | static A.id:3