成员函数
声明成员函数
类成员函数的声明和普通函数的声明类似。
class Demo {
private:
int value;
double num;
public:
int showFunc(int);
}
实现成员函数
类成员函数的实现和普通函数的实现有一些区别。类成员函数实现时函数名需要使用全名(限定名),成员函数可以访问类的私有成员。
int Demo::showFunc(int) {
}
内联成员函数
- 隐式内联。直接在类声明中用成员函数定义替换成员函数声明,则该函数会成为内联函数。
class Demo {
private:
int value;
double num;
public:
int showFunc(int v) { 实现细节; }
}
- 显式内联。在成员函数的定义处使用 inline 可以显式地将成员函数声明为内联函数。
class Demo {
private:
int value;
double num;
public:
int showFunc(int);
}
inline int Demo::showFunc(int v) {
}
构造函数
什么是构造函数
构造函数在创建对象时被自动调用。 特点:构造函数的函数名与类同名;没有返回类型;可以声明特征值不同的构造函数(重载)。 注意:当程序员没有声明构造函数,编译器会生成一个默认构造函数;一旦程序员声明了构造函数,编译器就不会再生成默认构造函数。
class Demo {
private:
int value;
double num;
public:
Demo();
Demo(int, double);
}
默认构造函数
Q:什么是默认构造函数? A:不接受任何参数的构造函数。
class Demo {
private:
int value;
double num;
public:
Demo();
}
Demo d1;
Demo d2();
Demo d3 = Demo();
复制构造函数
Q:什么是复制构造函数? A:只接受一个参数的构造函数,并且该参数的类型和类一样。
class Demo {
private:
int value;
double num;
public:
Demo(const Demo &);
}
Demo d1 = d;
Demo d2 = Demo(d);
容易混淆:复制构造函数和重载赋值运算符的使用时机。
当程序员没有声明复制构造函数,编译器会生成一个默认复制构造函数;一旦程序员声明了复制构造函数,编译器就不会再生成默认赋值构造函数。默认的复制构造函数的实际效果就是逐成员复制(浅拷贝)。对于成员函数需要使用动态内存分配的情况时,需要定义复制构造函数(深拷贝)。
转换构造函数
Q:什么是转换构造函数? A:只接受一个参数的构造函数,并且该参数的类型是其他类型。该构造函数可以将其他类型的变量转换为类类型。
class Demo {
private:
int value;
double num;
public:
Demo(Type t);
}
Type tmp;
Demo d1 = tmp;
Demo d2;
d2 = tmp;
Demo d3 = Demo(tmp);
其中 Type 为除了 Demo 之外的类型,可以是基本数据类型,也可以是程序员自定义的类型。
定义了转换构造函数之后就可以让其他类型变量自动转换为类类型,但是有时候这种特性并不招人喜欢,使用 explicit 关键字可以关闭隐式转换。
析构函数
析构函数在对象被销毁时被编译器自动调用。 特点:函数名为类名前面加上~;没有返回类型;没有参数。 注意:构造函数可以有参数,因此可以被重载,但是析构函数不接受参数,因此一个类只能有一个析构函数;通常,不需要我们编写析构函数,但是当类成员涉及动态内存分配时,需要编写析构函数。
class Demo {
private:
int value;
double num;
public:
~Demo();
}
运算符重载
运算符重载格式:
returnType operator[op](argList);
运算符重载的参数必须至少有一个是自定义类型;不能更改运算符的操作对象数目;运算符重载可以是成员函数,也可以是非成员函数,不过非成员函数通常被设为友元函数;. .* :: ?: sizeof 这5个运算符不能被重载。
class Demo {
private:
int value;
double num;
public:
Demo & operator*(double);
friend std::ostream & operator<<(std::ostream &, const Demo &);
}
Demo & operator+(const Demo & d1, const Demo & d2);
Demo & Demo::operator*(double d) {
}
std::ostream & operator<<(std::ostream & out, const Demo & d) {
}
Demo & operator+(const Demo & d1, const Demo & d2) {
}
注意:友元函数的关键字 friend 只能出现在类内,即只能在函数声明时使用,在函数定义处不能出现 friend (explicit 关键字也一样),详见 operator<< 的函数定义和函数实现。
转换函数
转换构造函数可以将其他类型对象转换为类类型;而转换函数则是反过来将类类型转换为其他类型。 特点:转换函数没有返回类型,因为返回的类型已经由 typeName 表明了;转换函数没有参数,因为参数其实就是通过隐式传递的 *this;转换函数必须是成员函数,因为传递的参数就是类对象。
class Demo {
private:
int value;
double num;
public:
operator typeName();
}
C++11 之后可以用 explicit 关键字关闭隐式转换。
小结
没有返回类型的函数:构造函数、析构函数、转换函数; 函数名固定的函数:构造函数和析构函数; 一定没有参数的函数:析构函数和转换函数; 只能出现在类声明中的关键字:friend、explicit; 不能重载的运算符:sizeof . .* :: ?:
|