定义的复制构造函数的默认行为c ++
default behaviour of defined copy constructor c++
假设我为 class B 定义了一个复制函数,它继承了 A 并且还有一个成员变量。
在 copt c'tor 体内我写了一些代码,但是在初始化列表中我没有显式调用 A c'tor(也不是复制 c'tor),也没有初始化成员变量。
在这种情况下,A默认c'tor将在到达B'复制c'tor主体之前被默认调用。
但是成员变量会怎样呢?
他们会用默认的 c'tor 初始化还是用他们的副本 c'tor 与争论对象的成员一起初始化(参数对象 == 给 B 副本 c'tor)。
此外,如果在初始化列表中调用某些成员的复制c'tor/c'tor或父class复制c'tor/c'tor - 会这种行为会改变吗?
我知道如果我们没有明确定义复制 c'tor:调用父 Class 和成员复制 c'tor。
我应该在这里期待什么?
如果你写了一个拷贝构造函数并且没有初始化一个成员变量那么它将被默认初始化。
这同样适用于基类,在大多数情况下,它们被视为与成员变量相同。
下面是一些示例代码,用于演示:
#include <iostream>
using namespace std;
struct S
{
S() { cout << "S()\n"; }
S(S const &) { cout << "S(S&)\n"; }
};
struct T : S
{
T() {}
T(T const &t) {}
// you have to explicitly write this if you want it
// T(T const &t): S(t) {}
// ^^^^
};
int main()
{
T t;
T u(t);
}
基础 class 子对象在这种情况下将被默认初始化。参见 [class.base.init]/8:
In a non-delegating constructor, if a given potentially constructed
subobject is not designated by a mem-initializer-id (including the
case where there is no mem-initializer-list because the constructor
has no ctor-initializer), then
- if the entity is a non-static data member that has a brace-or-equal-initializer [..]
- otherwise, if the entity is an anonymous union or a variant member (9.5), no initialization is performed;
- otherwise, the entity is default-initialized (8.5).
并且在[special]/5:
中定义了一个可能构造的子对象
For a class, its non-static data members, its non-virtual direct base
classes, and, if the class is not abstract (10.4), its virtual base
classes are called its potentially constructed subobjects.
假设我为 class B 定义了一个复制函数,它继承了 A 并且还有一个成员变量。 在 copt c'tor 体内我写了一些代码,但是在初始化列表中我没有显式调用 A c'tor(也不是复制 c'tor),也没有初始化成员变量。
在这种情况下,A默认c'tor将在到达B'复制c'tor主体之前被默认调用。 但是成员变量会怎样呢? 他们会用默认的 c'tor 初始化还是用他们的副本 c'tor 与争论对象的成员一起初始化(参数对象 == 给 B 副本 c'tor)。
此外,如果在初始化列表中调用某些成员的复制c'tor/c'tor或父class复制c'tor/c'tor - 会这种行为会改变吗?
我知道如果我们没有明确定义复制 c'tor:调用父 Class 和成员复制 c'tor。
我应该在这里期待什么?
如果你写了一个拷贝构造函数并且没有初始化一个成员变量那么它将被默认初始化。
这同样适用于基类,在大多数情况下,它们被视为与成员变量相同。
下面是一些示例代码,用于演示:
#include <iostream>
using namespace std;
struct S
{
S() { cout << "S()\n"; }
S(S const &) { cout << "S(S&)\n"; }
};
struct T : S
{
T() {}
T(T const &t) {}
// you have to explicitly write this if you want it
// T(T const &t): S(t) {}
// ^^^^
};
int main()
{
T t;
T u(t);
}
基础 class 子对象在这种情况下将被默认初始化。参见 [class.base.init]/8:
In a non-delegating constructor, if a given potentially constructed subobject is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then
- if the entity is a non-static data member that has a brace-or-equal-initializer [..]
- otherwise, if the entity is an anonymous union or a variant member (9.5), no initialization is performed;
- otherwise, the entity is default-initialized (8.5).
并且在[special]/5:
中定义了一个可能构造的子对象For a class, its non-static data members, its non-virtual direct base classes, and, if the class is not abstract (10.4), its virtual base classes are called its potentially constructed subobjects.