默认分配和初始化的方法分别为 “成员分配”和 “成员初始化,”。成员分配包括一次复制到另一个对象,成员,,就象分别为每个成员。成员初始化包括一次复制到另一个对象,成员,,就象单个初始化每个成员。两者之间的主要区别在于成员分配调用每个成员的赋值运算符 (),operator=,而成员初始化调用每个成员的复制构造函数。
成员分配由赋值运算符仅执行声明在窗体中:
type type :: operator= ( [const |volatile] type )
,如果满足以下任何一个存在,成员分配的默认未能生成赋值运算符:
成员类具有 const 成员。
成员类具有引用成员。
成员类或其基类私自赋值运算符 (operator=)。
基类或成员类没有赋值运算符 (operator=)。
默认成员初始化的未能生成复制构造,如果类或其基类具有私有复制构造函数或,如果满足以下任何一个存在:
成员类具有 const 成员。
成员类具有引用成员。
成员类或其基类具有私有复制构造函数。
基类或成员类没有复制构造函数。
默认赋值运算符和复制构造函数特定类的总是声明,但是,它们未定义,除非两个满足以下条件:
类为该副本不提供用户定义的函数。
程序需要函数存在。此要求存在,如果需要复制的成员的分配或初始化遇到或,如果类的 operator= 函数的地址中采用。
如果这两个条件不满足,不要求编译器生成默认赋值运算符和复制构造函数的代码 (此代码的取消是 Microsoft C++ 编译器执行的优化)。具体而言,因此,如果采用类型参数 “引用 类名称的类声明用户定义的 operator= ,”默认赋值运算符不生成。如果类声明复制构造函数,默认的复制构造函数不生成。
因此,对于特定类 A,以下说明始终存在:
// Implicit declarations of copy constructor
// and assignment operator.
A::A( const A& );
A& A::operator=( const A& );
只能在必须提供定义 (按照上面的标准)。前面示例中演示的复制构造函数被视为类的公共成员函数。
默认赋值运算符允许将特定类的对象分配给一个公共基类类型的对象。考虑下列代码:
示例
// spec1_memberwise_assignment_and_initialization.cpp
#include<stdio.h>
class Account
{
protected:
int _balance;
public:
int getBalance()
{
return _balance;
}
};
class Checking : public Account
{
private:
int _fOverdraftProtect;
public:
Checking(int balance, int fOverdraftProtect)
{
_balance = balance;
_fOverdraftProtect = fOverdraftProtect;
}
};
int main()
{
Account account;
Checking checking(1000, 1);
account = checking;
printf_s("Account balance = %d\n", account.getBalance());
}
注释
在前面的示例中,赋值运算符选择是 Account::operator=。由于默认 operator= 函数采用类型 Account& 的参数 (引用 Account), checkingAccount subobject 复制到 account; fOverdraftProtect 不会复制。