c++类的声明
class Car
{
private://成员变量的声明
string brand;//品牌
double price;
int wheel;//轮子
public:
//这里把所有的成员函数都定义为内联函数
//这里都是内联函数,内联函数要去替换所有调用他们的地方,多份拷贝和源代码都存放在代码段空间
//既然分配到代码段空间,那就是被分配存储空间了,所以算定义性声明
//另外补充两点:
//1.类中成员函数放在代码段中,不占用内存空间,创建对象,其实就是创建了一个对象的内存区域,然后初始化,创建对象不会为成员函数分配空间。成员函数放在代码区,多个对象共享。函数是不用也不会再"创建"的,他们都是编译时就确定好了的;
//2.在类中定义的成员函数默认是内联(inline)的,会在调用处展开,所以在一个程序中可能存在该函数的多个拷贝(在类中声明却在类外定义的函数除外)
string getBrand(void)
{
return this -> brand;
}
double getPrice(void)
{
return this -> price;
}
int getWheel(void)
{
return this -> wheel;
}
};
对象的定义
- 广义声明
- int num;//定义性声明(定义),分配存储空间,分配垃圾值
- int num = 10;//定义性声明(定义)中的特例,既分配空间,又初始化
- extern int num;//引用性声明,不分配存储空间,不分配值
- int num;//定义性声明(定义),分配存储空间,分配垃圾值
- 前者是“定义性声明defining declaration”或者称为“定义definition”,而后者是“引用性声明referncing declaration”
- 从广义的角度来讲声明中包含着定义,即定义是声明的一个特例,所以并非所有的声明都是定义,例如:int a 它既是声明,同时又是定义。然而对于 extern a 来讲它只是声明不是定义。
一般的情况下我们常常这样叙述,把建立空间的声明称之为“定义”,而把不需要建立存储空间的声明称之为“声明”。很明显我们在这里指的“声明”是范围比较窄的,即狭义上的声明,也就是说非定义性质的声明。
下面讨论对象的定义性声明
int main(void)
{
Car car;//定义性声明,个人不喜欢这种写法
cout << sizeof(car) << endl;//0+32+4
cout << car.getBrand() << endl;
cout << car.getPrice() << endl;
cout << car.getWheel() << endl;
return 0;
}
output:
walter@i386:~/test$ g++ main.cpp
walter@i386:~/test$ ./a.out
36
-1.24924
-1074529044
walter@i386:~/test$ g++ main.cpp
walter@i386:~/test$ ./a.out
36
-0.0800841
-1078689684
walter@i386:~/test$
- 经过验证Car car;调用的是Car类中默认的无参构造函数,当然默认构造函数都是无参的。此时还没有重载任何构造函数。
- 验证结果表明:
- car被分配存储空间了 -> 定义性声明 -> 查看好多文章都直接说“对象的定义”
- 但是所有属性里存的都是垃圾值
- 但是我有个问题:为什么
Car car;
就会去调用构造函数,现在暂且把他理解为C++的一种机制吧
- 注意:这是是没有重载任何构造函数,默认构造函数依然生效
- 借助上面的代码,我们在做一个小实验,验证一个东西
int main(void)
{
Car car();//注意这里有()
cout << sizeof(car) << endl;//0+32+4
cout << car.getBrand() << endl;
cout << car.getPrice() << endl;
cout << car.getWheel() << endl;
return 0;
}
output:
编译直接报错,看来这种写法不对,我们再换一种
int main(void)
{
Car car = Car();//这种写法和java对象的定义很像,我喜欢这种
cout << sizeof(car) << endl;//0+32+4
cout << car.getBrand() << endl;
cout << car.getPrice() << endl;
cout << car.getWheel() << endl;
return 0;
}
output:
walter@i386:~/test$ g++ main.cpp
walter@i386:~/test$ ./a.out
36
0
0
walter@i386:~/test$ g++ main.cpp
walter@i386:~/test$ ./a.out
36
0
0
构造函数
- 这里暂时不研究拷贝构造函数
- 上面没有重载任何构造函数,默认构造函数依然生效
- 但是只要人为重载任意一种参数列表的构造函数,默认构造函数都失效
- 所以为了保留无参构造函数都会重载一次无参构造函数
- 下面开始实验:
class Car
{
private:
string brand;
double price;
int wheel;
public:
Car car()
{
}
Car car(string brand,double price,int wheel)
:brand(brand),price(price),wheel(wheel)
{//构造函数列表初始化,提高程序运行效率
//只支持将参数通过赋值运算赋值给类成员
//也就是这里不能用引用
//因为形参的引用并不会copy实参的值,只会映射到内存空间
}
string getBrand(void)
{
return this -> brand;
}
double getPrice(void)
{
return this -> price;
}
int getWheel(void)
{
return this -> wheel;
}
};
int main(void)
{
Car car;//不喜欢
cout << sizeof(car) << endl;//0+32+4
cout << car.getBrand() << endl;
cout << car.getPrice() << endl;
cout << car.getWheel() << endl;
return 0;
}
output:
walter@i386:~/test$ ./a.out
36
-0.2874
-1076730676
int main(void)
{
Car car();//
cout << sizeof(car) << endl;//0+32+4
cout << car.getBrand() << endl;
cout << car.getPrice() << endl;
cout << car.getWheel() << endl;
return 0;
}
output:
编译报错
int main(void)
{
Car car = Car();//喜欢
cout << sizeof(car) << endl;//0+32+4
cout << car.getBrand() << endl;
cout << car.getPrice() << endl;
cout << car.getWheel() << endl;
return 0;
}
output:
walter@i386:~/test$ ./a.out
36
-0.0281008
-1080244612
int main(void)
{
Car car("BMW",100,4);//不喜欢
cout << sizeof(car) << endl;//0+32+4
cout << car.getBrand() << endl;
cout << car.getPrice() << endl;
cout << car.getWheel() << endl;
return 0;
}
output:
walter@i386:~/test$ ./a.out
36
BMW
100
4
int main(void)
{
Car car = Car("BMW",100,4);//喜欢
cout << sizeof(car) << endl;//0+32+4
cout << car.getBrand() << endl;
cout << car.getPrice() << endl;
cout << car.getWheel() << endl;
return 0;
}
output:
walter@i386:~/test$ ./a.out
36
BMW
100
4
最后,构造函数的默认参数,将在函数的默认参数里分析。