前文:
在定义变量和对象时,可以立即为它们指定初始值。 始终使用其可用构造函数之一初始化类类型对象。 C已经支持数组和结构初始化列表,该列表由一对花括号包围的常量表达式列表组成。
C ++支持类似的初始化,称为一致性初始化(Uniform initialization)。 它使用以下语法:
Type obj {val_list};
当使用对象列表定义对象时,每个单独的对象可以使用其自己的一致性初始化。
一致性初始化可用于初始化对象或变量,也可用于初始化构造函数中的数据成员或隐式地在函数的return语句中。 例子:
class Person{
public:
Person(std::string const &pname, std::string const paddr,size_t age):
d_name {name},d_addr {paddr},d_age {age}
{}
}
default和delete
在类设计中经常遇到两种情况:
- 提供构造函数的类显式必须定义默认构造函数;
- 类(例如,实现流的类)不能通过从该类的现有对象拷贝(称为复制构造)来初始化对象,并且不能将对象分配给彼此。
一旦类定义了至少一个构造函数,其默认构造函数就不会被编译器自动定义。 C ++通过提供“= default”语法来放松这种限制。 使用其默认构造函数声明指定`= default'的类指示应由编译器提供普通的默认构造函数。 一个普通的默认构造函数执行以下操作:
- 该类的内置类型的数据成员尚未初始化。
- 其组合(类类型)数据成员由其默认构造函数初始化。
- 如果该类派生自基类,则基类由其默认构造函数初始化。
还可以为复制构造函数,重载赋值运算符和析构函数提供简单的实现。
const成员函数和const对象
关键字const通常用在成员函数的参数列表后面。 此关键字表示成员函数不会更改其对象的数据成员。 这些成员函数称为const成员函数。 在Person类中,我们看到访问器函数被声明为const:
class Person
{
....
const std::string name() const;
const std::string address() const;
const std::string contact() const;
const size_t age() const;
.....
};
经验法则:关键字const左侧出现的任何一个,都不会改变。 对于成员函数,这应该被解释为“不改变自己的数据”。
实现const成员函数时,必须重复const属性:
const std::string Person::name() const{
return d_name;
}
const std::string Person::address() const{
return d_address;
}
const成员函数用于防止无意中修改数据。 除了构造函数和析构函数之外,只有const成员函数可以与const对象(plain,引用或指针)一起使用。
const对象经常作为const &出现在函数的参数中。 在这些函数内部,只能使用对象的const成员。 这是一个例子
void display_person(Person const &p)
{
cout << "姓名:" << p.name() << endl;
cout << "地址:" << p.address() << endl;
cout << "电话:" << p.contact() << endl;
cout << "年龄:" << p.age() << endl;
};
const成员函数属性可用于重载成员函数。 当函数被const属性重载时,编译器使用最接近对象的const限定的成员函数,请参考如下示例:
类接口的定义:声明了两个不同版本的函数原型
class Person{
....
void show_age();
void show_age() const;
....
}
类实现:我们对show_age成员函数重载了一个常量版本的和非常量版本的
void Person::show_age(){
cout << "非const版本: " << d_name << "今年" << d_age << "岁" << endl;
}
void Person::show_age() const{
cout << "const版本: " << d_name << "今年" << d_age << "岁" << endl;
}
正如下面的调用示例,我们分别创建了一个常量版本的Person 对象 list和非常量版本的Person对象 yanlan。
- 当对象是const对象时,只能使用const成员函数。
- 当对象不是const对象时,使用非const成员函数,除非只有const成员函数可用。 在这种情况下,使用const成员函数。
类设计的一般原则:成员函数应始终赋予const属性,除非它们的作用实际上是用于修改了对象的数据成员
。
#include "./person.cpp"
#include <iostream>
int main(int argc, char const *argv[])
{
/* code */
Person const lisa = Person{"Lisa", "东台路117号A座", 23};
Person yalan = Person{"Yan Lan", "沙金路4栋618", 38};
lisa.show_age();
yalan.show_age();
return 0;
}
输出效果