考虑以下代码
#include <iostream>
using namespace std;
class A
{
int x;
public:
A() { cout << "A's constructor called " << endl; }
};
class B
{
public:
static A a;
B() { cout << "B's constructor called " << endl; }
static A getA() { return a; }
};
A B::a; // definition of a
int main()
{
B b1, b2, b3;
A a = b1.getA();
cout<<&a<<endl;
cout<<&B::a;
return 0;
}
输出为
A's constructor called
B's constructor called
B's constructor called
B's constructor called
0x7fff03081280
0x601194
现在让我们考虑另一个类似的代码
#include <iostream>
using namespace std;
class A
{
int x;
public:
A() { cout << "A's constructor called " << endl; }
};
class B
{
public:
static A a;
B() { cout << "B's constructor called " << endl; }
static A getA() { return a; }
};
A B::a; // definition of a
int main()
{
B b1, b2, b3;
A a ;
a= b1.getA();
cout<<&a<<endl;
cout<<&B::a;
return 0;
}
输出为
A's constructor called
B's constructor called
B's constructor called
B's constructor called
A's constructor called
0x7ffc485a1070
0x601194
现在我的问题是,为什么在第一种情况下,A的构造函数仅被调用一次,而在第二种代码中,其调用两次。
两个输出&a和&B :: a也不同,所以这意味着它们是两个不同的对象。
请解释为什么会这样。
答案 0 :(得分:3)
在您的第一个代码中
A a = b1.getA();
A
的复制构造函数被调用,但不会生成任何输出。自己定义它,您将获得与第二个代码类似的输出。
答案 1 :(得分:1)
嗯,B::a
是B的(公共)静态成员实例,否则是非常普通的类A
。因此,记录的第一个A
的构造函数是B::a
的构造函数,应该在控件进入main
之前对其进行初始化,但是接下来您要在本地创建一个A
的单独实例main
,它是与其他main
的局部变量(在这里,紧随所有B
之后)一起按顺序构造的,自然与B::a
不同。 / p>
答案 2 :(得分:1)
现在我的问题是,为什么在第一种情况下,A的构造函数仅被调用一次,而在第二种代码中,其调用两次。
因为在第一种情况下,您仅默认初始化静态B::a
,并复制初始化本地a
。
在第二个中,您默认初始化了两个对象。
关键区别在于,您仅在默认构造函数中打印一条消息,而在副本构造函数中不打印任何内容。
两个输出&a和&B :: a也不同,所以这意味着它们是两个不同的对象。
是正确的。 a
是局部变量,而B::a
是静态成员变量。它们是不同的对象。
答案 3 :(得分:1)
类类型的静态成员变量表示具有整个过程寿命的存储。就这样初始化它,到达程序入口点之前的某个点-main()的开始。那是第一个构造函数调用。
行
A a = b1.getA();
通过调用复制构造函数并通过返回值优化和复制省略初始化对象a,没有默认的构造函数调用。
第二种形式:
A a; // A() call
a = b1.getA(); // operator= call
修改后的类
class A
{
int x;
public:
A(const A& a): x(a.x) { cout << "A's copy constructor called " << endl; }
A(A&& a): x(a.x) { a.x = 0; cout << "A's move constructor called " << endl; }
const A& operator=(const A& a) { x = a.x; cout << "A's copy operator= called " << endl; }
A() { cout << "A's constructor called " << endl; }
};
在第一种情况下将给出以下输出:
A's constructor called
B's constructor called
B's constructor called
B's constructor called
A's copy constructor called
第二种情况将导致:
A's constructor called
B's constructor called
B's constructor called
B's constructor called
A's constructor called
A's copy constructor called
A's copy operator= called
答案 4 :(得分:0)
很容易理解,每当要创建的类实例(对象)与关联的构造函数一起被调用时,就可以理解。
现在我的问题是,为什么在第一种情况下,A的构造函数仅被调用一次,而在第二种代码中,其两次被调用。
您直接在堆栈中创建第二个对象,在以后的情况下调用构造函数,第一个是静态的,第二个通过以下语句在堆栈中创建对象。
path = 'C:\\Users\\ABC\\Desktop\\'
files = glob.glob(path+'*.csv')
在第一种情况下,不是调用构造函数,而是调用拷贝构造函数,因此这就是为什么您第二次不获取print语句的原因。
A a ;