class Book{
private :
string book_name;
double book_cost;
int book_price;
public :
Book(string name , double cost , int price):book_name(name) , book_cost(cost) , book_price(price) {};
string see_book_name() {
return book_name;
}
};
关于构造函数:
通常我们对类成员进行“初始化”有两种方式:
1. 构造函数后面跟冒号;
2. 构造函数里面对成员进行赋值。
两种方法其实是完全不同的。
class A
{
public:
A(int& c)
{
_a = 1;
_b = 2;
_c = c;
}
protected:
int _a;
const int _b;
int& _c;
};
如上面这段代码:这是构造函数里对成员进行赋值。但编译器会报错,原因在于const对象不能做左值,c是指向int型的引用,也不能直接绑定到一个int型字面值上。
这种错误就类似于 :const int a = 1 , int & b = 2;
这种情况下,我们就应该使用构造函数后面跟冒号的形式:
class A
{
public:
A(int& c): _b(2), _c(c)
{
_a = 1;
}
protected:
int _a;
const int _b;
int& _c;
};
究其原因在于:const和引用必须在声明的时候就初始化,换句话说就是在给const和引用类型变量分配内存的时候就初始化。
现在我们就可以知道了,其实在构造函数里面调用等于号并不是真正意义上的“初始化”。这个过程相当于:
1. 调用编译器创建的默认构造函数,先创建这个对象;
2. 创建完后再进行赋值操作。
而在构造函数后面跟冒号,就相当于:
1. 系统创建成员变量并且初始化。也就是系统为成员变量分配了一块内存并且把相应的数据给填了进去。而构造函数里面调用等于号的方式是分配好后再进行赋值,多了一个步骤。
成员初始化的顺序和他们在类定义中出现的顺序是一样的,所以在写构造函数时也要按照他们的出现顺序进行初始化。否则会出现一些错误
如:
class A {
private:
int i;
int j;
public:
A(int val):j(val) , i(j){} //会出现j未定义的错误
};