2.3.3 定义对象
下列语句定义了五个变量:
int units_sold; double sales_price, avg_price; std::string title; Sales_item curr_book;
|
每个定义都是以类型标识符(type specifier)开始,后面紧跟着以逗号分开的含有一个或多个标识符的列表。分号结束定义。类型标识符指定与对象相关联的类型:int、double、std::string和Sales_item都是类型名。其中int和double是内置类型,std::string是标准库定义的类型,Sales_item是我们在1.5节使用的类型,将会在后面章节定义。类型决定了分配给变量的存储空间的大小和可以在其上执行的操作。
多个变量可以定义在同一条语句中:
double salary, wage; // defines two variables of type double int month, day, year; // defines three variables of type int std::string address; // defines one variable of type std::string
|
1. 初始化
变量定义指定了变量的类型和标识符,也可以为对象提供初始值。定义时指定了初始值的对象被称为是已初始化的(initialized)。C++(www.cppentry.com)支持两种初始化变量的形式:拷贝初始化(copy- initialization)和直接初始化(direct-initialization)。拷贝初始化语法用等号(=),直接初始化是把初始化式放在括号中:
int ival(1024); // direct-initialization int ival = 1024; // copy-initialization |
这两种情形中,ival都被初始化为1024。
虽然在此处还有点朦胧,但是在C++(www.cppentry.com)中理解“初始化不是赋值”是必要的。初始化指创建变量并给它赋初始值,而赋值则是擦除对象的当前值并用新值代替。
使用=来初始化变量使得许多C++(www.cppentry.com)编程(www.cppentry.com)新手感到迷惑,他们很容易把初始化当成是赋值的一种形式。但是在C++(www.cppentry.com)中初始化和赋值是两种不同的操作。这个概念特别容易误导人,因为在许多其他的语言中这两者的差别不过是枝节问题而已可以被忽略。即使在C++(www.cppentry.com)中也只有在编写非常复杂的类时才会凸显这两者之间的区别。无论如何,这是一个关键的概念,也是我们将会在整本书中反复强调的概念。
当初始化类类型对象时,拷贝初始化和直接初始化之间的差别是很微妙的。我们在第13章再详细解释它们之间的差别。现在我们只须知道,直接初始化语法更灵活且效率更高。
2. 使用多个初始化式
初始化内置类型的对象只有一种方法:提供一个值,并且把这个值复制到新定义的对象中。对内置类型来说,拷贝初始化和直接初始化几乎没有差别。
对类类型的对象来说,有些初始化仅能用直接初始化完成。要想理解其中缘由,需要初步了解类是如何控制初始化的。
每个类都可能会定义一个或几个特殊的成员函数(1.5.2节)来告诉我们如何初始化类类型的变量。定义如何进行初始化的成员函数称为构造函数(constructor)。和其他函数一样,构造函数能接受多个参数。一个类可以定义几个构造函数,每个构造函数必须接受不同数目或者不同类型的参数。
我们以string类为例(string类将在第3章详细讨论)。string类型在标准库中定义,用于存储不同长度的字符串。使用string时必须包含string头文件。和IO类型一样,string定义在std命名空间中。
string类定义了几个构造函数,使得我们可以用不同的方式初始化string对象。其中一种初始化string对象的方式是作为字符串字面值的副本:
#include // alternative ways to initialize string from a character string literal std::string titleA = "C++(www.cppentry.com) Primer, 4th Ed."; std::string titleB("C++(www.cppentry.com) Primer, 4th Ed."); |
本例中,两种初始化方式都可以使用。两种定义都创建了一个string对象,其初始值都是指定的字符串字面值的副本。
也可以通过一个计数器和一个字符初始化string对象。这样创建的对象包含重复多次的指定字符,重复次数由计数器指定:
std::string all_nines(10, '9'); // all_nines= "9999999999" |
本例中,初始化all_nines的唯一方法是使用直接初始化。有多个初始化式时不能使用拷贝初始化。
3. 初始化多个变量
当一个定义中定义了两个以上变量的时候,每个变量都可能有自己的初始化式。 对象的名字立即变成可见,所以可以用同一个定义中前面已定义变量的值初始化后面的变量。已初始化变量和未初始化变量可以定义在同一个定义中定义。两种形式的初始化文法可以相互混合。
#include // ok: salary defined and initialized before it is used to initialize wage double salary = 9999.99, wage(salary + 0.01); // ok: mix of initialized and uninitialized int interval, month = 8, day = 7, year = 1955; // ok: both forms of initialization syntax used std::string title("C++(www.cppentry.com) Primer, 4th Ed."), publisher = "A-W"; |
对象可以用任意复杂的表达式(包括函数的返回值)来初始化:
double price = 109.99, discount = 0.16; double sale_price = apply_discount(price, discount); |
本例中,函数apply_discount接受两个double类型的值并返回一个double类型的值。将变量price和discount传递给函数,并且用它的返回值来初始化sale_price。
习题
习题2.15 下面两个定义是否不同?有何不同?
int month = 9, day = 7; int month =09, day = 07;
|
如果上述定义有错的话,那么应该怎样改正呢
习题2.16 假设calc是一个返回double对象的函数,下面哪些是非法定义 改正所有的非法定义。
(a) int car = 1024, auto = 2048; (b) int ival = ival; (c) std::cin >> int input_value; (d) double salary = wage = 9999.99; (e) double calc = calc();
|
【责任编辑:
董书 TEL:(010)68476606】