如果方法或函数要返回局部对象,则应返回对象,而不是对象的引用。在这种情况下,将使用复制构造函数来生成返回的对象。
如果方法或函数返回一个没有公有复制构造函数的类(如ostream)的对象,它必须返回一个指向这种对象的引用。
最后,有些方法和函数(如重载的复制操作符)可以返回对象,也可以返回指向对象的引用,在这种情况下应首选引用,因为其效率更高。
class string{
private:
char * str;
int len;
public:
string(char *str);
}
string *pveg=new string("cabbage heads home");的执行流程:
1.为对象分配内存str,len;
2.调用类构造函数,它将为"cabbage heads home"分配空间->将"cabbage heads home"复制到分配的内存空间中->将"cabbage heads home"的地址赋给str->将值19赋给len;
3.创建pveg变量;
4.将新点地址赋给pveg变量。
justtesting是类名,使用布局new操作符声明这个类的对象:
char * buffer=new char[30];
pc1=new (buffer) justtesting;
pc2=new justtesting;
使用布局new操作符为对象分配内存,必须确保其析构函数被调用。对于堆中创建的对象,可以用delete pc2;然而,对于用布局new操作符创建的pc1,却不能直接delete pc1;这是因为delete只能与常规new操作符配合使用。
解决方案是:
显示地为使用布局new操作符创建的对象调用析构函数:pc1->~justtesing();
然后再释放存储这个对象的缓冲区:delete []buffer;
class queue{
public:
queue(int qs);
private:
const int qsize;
}
queue::queue(int qs){qsize=qs;}
其中,qsize是常量,可以对它进行初始化,但不能给它赋值。概念上来说,调用构造函数时,对象将在花括号中的代码执行之前被创建。因此,调用queue(int qs)构造函数将导致程序首先给qsize分配内存;然后,程序再使用常规的赋值方法将值存储在内存中。因此,对于const数据成员,必须在执行到构造函数体之前,即创建对象时进行初始化,这需要用成员初始化列表。
成员初始化列表由逗号分隔的初始化列表组成,前面带冒号。如:
queue::queue(int qs):qsize(qs){}
对于const类成员,必须使用这种句法,另外,对于声明为引用的类成员,也必须使用,如:
class agency{..}
class agent{
private:
agency & belong;
}
agent::agent(agency & a):belong(a){}
这是因为引用和const数据相似,只能在被创建时初始化。
成员初始化列表只能用于构造函数,并且使用成员初始化列表的效率更高。而数据成员被初始化的顺序与它们出现在类声明中的顺序相同,与初始化器中的排列顺序无关。