成员函数其定义位于类声明中的函数都将自动成为内联函数。内联函数的特殊规则要求在每个使用他们的文件中都对其进行定义。确保内联定义对多文件程序中的所有文件都可用的、最简便的方法是:将内联定义在定义类的头文件中。
一般来说,一种做饭是在在数据成员名中使用m_前缀,另一种做法是在成员名中使用后缀_。
c++提供了两种使用构造函数来初始化对象的方式。
第一种方式是显式的调用构造函数:
Stock food = Stock("World Cabbage",250, 1,25);
另一种方式是隐式地调用构造函数
Stock garment("Furry Mason", 50, 2.5);
使用对象指针
Stock *pstock = new Stock("Electroshock Games", 18, 19.0);
构造函数被用来创建对象,而不能通过对象来调用。
当且仅当没有定义任何构造函数时,编译器才会提供默认构造函数。为类定义了构造函数后,程序员就必须为他提供默认的构造函数。如果提供了非默认构造函数,但没有提供默认构造函数,则下面的声明将出错:
Stock st;
在设计类时,通常应提供对所有类成员做隐式初始化的默认构造函数。如:
Stock::Stock()
{
company = "no name";
shares = 0;
share_val = 0.0;
total_val = 0.0;
}
什么时候应调用析构函数呢?这由编译器决定,通常不应该在代码中显式的调用析构函数。如果创建的是静态存储类对象,则其析构函数将在程序结束时自动被调用。如果创建的是自动存储类对象,则其析构函数将在程序执行完代码块时(该对象是在其中定义的)自动被调用。如果对象是通过new创建的,则它将驻留在栈内存或自由存储区中,当使用delete来释放内存时,其析构函数将自动被调用。最后,程序可以创建临时对象来完成特定的操作,在这种情况下,程序将在结束对该对象的使用时自动调用其析构函数。
下面的语句表明可以将一个对象赋给同类型的的另一个对象:
stock2 = stock1;
在默认情况下,将一个对象赋给同类型的另一个对象时,C++将源对象的每个数据成员的内容复制到目标对象中相应的数据成员中。
stock1 = Stock("Nifty", 10, 50.0);
stock1对象已经存在。因此这条语句不是对stock进行初始化,而是将新值赋给它。这是通过让构造程序创建一个新的、临时的对象,然后将其内容复制给stock1来实现的。随后程序调用析构函数,以删除该临时对象。
当对象这种自动变量被放在栈中,因此最后创建的对象将最先被删除,最先创建的对象将最后被删除。
#include "iostream"
using namespace std;
class Stock {
public:
void show() {
;
}
};
int main() {
const Stock stock;
stock.show();
return 0;
}
编译器将拒绝第二行。因为show()的代码无法确保调用对象不被修改(调用对象和const一样,不应该被修改)。
class Stock {
public:
void show() const{
;
}
};
show()的声明应该像上面这样。
如果构造函数只有一个参数,则可以使用下面的任何一种形式来初始化对象:
Bozo d = Bozo(44);
Bozo r(66);
Bozo t = 32;
每个成员函数(包括构造函数和析构函数)都有一个this指针。this指针指向调用对象。如果方法需要引用整个调用对象,则可以使用*this。在函数的括号后面使用const限定符将this限定为const,这样将不能使用this来修改对象的值。
Stock mystuff[4];
Stock stocks[4] = {
Stock("NanoSmart", 12.5,20),
Stock(),
Stock(),
Stock()
};
当程序创建未被显示初始化的类对象时,总是调用默认构造函数。
可以用构造函数来初始化数组元素,在这种情况下,必须为每个元素调用构造函数。
如果类包含多个构造函数,则可以对不同的元素使用不用的构造函数
初始化对象数组的方案是,首先使用默认构造函数创建数组元素,然后花括号中的构造函数将创建临时对象,然后将临时对象的内容复制到相应的元素中。
class Bakery{
const int Months =12;
double cost[Months];
} //这种行不通
class Bakery{
enum {Months =12};
double cost[Months];
}
class Bakery{
static const int Months =12;
double cost[Months];
}
这是行不通的,因为声明类只是描述了对象的形式,并没有创建对象。因此,在创建对象前,将没有用于存储值的空间。
第一种方式是在类中声明一个枚举。在类声明的枚举的作用域为整个类,因此可以用枚举为整形常量提供作用域为整个类的符号名称。用这种方式声明枚举并不会创建类数据成员,也就是说,所有对象中都不包含枚举。另外,Months只是一个符号名称,在作用域为整个类的代码中遇到他,编译器将用12来替换他。
第二种方式将创建一个名为Months的常量,该常量将与其他静态变量存储在一起,而不是存储在对象中。因此,只有一个Months常量,被所有Bakery对象共享。
c++提供了一种新枚举,其枚举量的作用域为类。
enum class egg{Small, Medium, Large};
enum class tshirt{Small, Medium, Large};
egg choice = egg::Large;
也可以使用struct代替class。
C++11作用域内枚举不能隐式地转换为整形。