标签:
缺省构造函数(指没有参数的构造函数)在C++语言中是一种让你无中生有的方法。构造函数能初始化对象,而缺省构造函数则可以不利用任何在建立对象时的外部数据就能初始化对象。有时这样的方法是不错的。例如一些行为特性与数字相仿的对象被初始化为空值或不确定的值也是合理的,还有比如链表、哈希表、图等等数据结构也可以被初始化为空容器。
class EquipmentPiece {
public:
EquipmentPiece(int IDNumber);
...
};
因为EquipmentPiece类没有一个缺省构造函数,所以在三种情况下使用它,就会遇到问题。第一中情况是建立数组时。一般来说,没有一种办法能在建立对象数组时给构造函数传递参数。所以在通常情况下,不可能建立EquipmentPiece对象数组:EquipmentPiece bestPieces[10]; // 错误!没有正确调用
// EquipmentPiece 构造函数
EquipmentPiece *bestPieces =
new EquipmentPiece[10]; // 错误!与上面的问题一样
int ID1, ID2, ID3, ..., ID10; // 存储设备ID号的
// 变量
...
EquipmentPiece bestPieces[] = { // 正确, 提供了构造
EquipmentPiece(ID1), // 函数的参数
EquipmentPiece(ID2),
EquipmentPiece(ID3),
...,
EquipmentPiece(ID10)
};
typedef EquipmentPiece* PEP; // PEP 指针指向
//一个EquipmentPiece对象
PEP bestPieces[10]; // 正确, 没有调用构造函数
PEP *bestPieces = new PEP[10]; // 也正确
for (int i = 0; i < 10; ++i) bestPieces[i] = new EquipmentPiece( ID Number );
// 为大小为10的数组 分配足够的内存 // EquipmentPiece 对象; 详细情况请参见条款M8 // operator new[] 函数 void *rawMemory = operator new[](10*sizeof(EquipmentPiece)); // make bestPieces point to it so it can be treated as an // EquipmentPiece array EquipmentPiece *bestPieces = static_cast<EquipmentPiece*>(rawMemory); // construct the EquipmentPiece objects in the memory // 使用"placement new" (参见条款M8) for (int i = 0; i < 10; ++i) new (&bestPieces[i]) EquipmentPiece( ID Number );
// 以与构造bestPieces对象相反的顺序 // 解构它。 for (int i = 9; i >= 0; --i) bestPieces[i].~EquipmentPiece(); // deallocate the raw memory operator delete[](rawMemory);
delete [] bestPieces; // 没有定义! bestPieces
//不是用new操作符分配的。
template<class T>
class Array {
public:
Array(int size);
...
private:
T *data;
};
template<class T>
Array<T>::Array(int size)
{
data = new T[size]; // 为每个数组元素
... //依次调用 T::T()
}
class EquipmentPiece {
public:
EquipmentPiece( int IDNumber = UNSPECIFIED);
...
private:
static const int UNSPECIFIED; // 其值代表ID值不确定。
};
EquipmentPiece e; //这样合法
class Name { // for names of things
public:
Name(const string& s); // 转换 string 到
// Name
...
};
class Rational { // 有理数类
public:
Rational(int numerator = 0, // 转换int到
int denominator = 1); // 有理数类
...
};
class Rational {
public:
...
operator double() const; // 转换Rational类成
}; // double类型
Rational r(1, 2); // r 的值是1/2
double d = 0.5 * r; // 转换 r 到double,
// 然后做乘法
以上这些说明只是一个复习,我真正想说的是为什么你不需要定义各种类型转换函数。
根本问题是当你在不需要使用转换函数时,这些函数却会被调用运行。结果,这些不正确的程序会做出一些令人恼火的事情,而你又很难判断出原因。
让我们首先分析一下隐式类型转换运算符,它们是最容易处理的。假设你有一个如上所述的Rational类,你想让该类拥有打印有理数对象的功能,就好像它是一个内置类型。因此,你可能会这么写:
Rational r(1, 2); cout << r; // 应该打印出"1/2"
class Rational {
public:
...
double asDouble() const; //转变 Rational
}; // 成double
Rational r(1, 2);
cout << r; // 错误! Rationa对象没有
// operator<<
cout << r.asDouble(); // 正确, 用double类型
//打印r
template<class T>
class Array {
public:
Array(int lowBound, int highBound);
Array(int size);
T& operator[](int index);
...
};
bool operator==( const Array<int>& lhs,
const Array<int>& rhs);
Array<int> a(10);
Array<int> b(10);
...
for (int i = 0; i < 10; ++i)
if (a == b[i]) { // 哎呦! "a" 应该是 "a[i]"
do something for when
a[i] and b[i] are equal;
}
else {
do something for when they're not;
}
for (int i = 0; i < 10; ++i) if (a == static_cast< Array<int> >(b[i])) ...
template<class T>
class Array {
public:
...
explicit Array(int size); // 注意使用"explicit"
...
};
Array<int> a(10); // 正确, explicit 构造函数
// 在建立对象时能正常使用
Array<int> b(10); // 也正确
if (a == b[i]) ... // 错误! 没有办法
// 隐式转换
// int 到 Array<int>
if (a == Array<int>(b[i])) ... // 正确,显式从int到
// Array<int>转换
// (但是代码的逻辑
// 不合理)
if (a == static_cast< Array<int> >(b[i])) ...
// 同样正确,同样
// 不合理
if (a == (Array<int>)b[i]) ... //C风格的转换也正确,
// 但是逻辑
// 依旧不合理
if (a == static_cast<Array<int>>(b[i])) ...
template<class T>
class Array {
public:
class ArraySize { // 这个类是新的
public:
ArraySize(int numElements): theSize(numElements) {}
int size() const { return theSize; }
private:
int theSize;
};
Array(int lowBound, int highBound);
Array(ArraySize size); // 注意新的声明
...
};
Array<int> a(10);
bool operator==( const Array<int>& lhs,
const Array<int>& rhs);
Array<int> a(10);
Array<int> b(10);
...
for (int i = 0; i < 10; ++i)
if (a == b[i]) ... // 哎呦! "a" 应该是 "a[i]";
// 现在是一个错误。
More Effective C++----(4)避免无用的缺省构造函数 & (5)谨慎定义类型转换函数
标签:
原文地址:http://blog.csdn.net/qianqin_2014/article/details/51315716