文章目录- 类
- 1. struct和class的区别
- 2. explicit构造
- 3. const和mutable
- 4. 自引用
- 5. static
- *复数的实现*
- 6.成员函数重载
- 7.运算符重载
- 8.new
- 9.析构函数
- 10.friend
- 10.类的继承
- 11.多态
- 12.virtual
- 看的不过瘾?
类
1. struct和class的区别
如果从C语言的视角来看,所谓类就是能够调用自身成员的结构体。而在C++中,关键字struct 虽然仍旧保留,但已非C语言中的结构体,而是表示默认成员共有的class 。
即在C++中,struct C{/*code*/} 和class C{public:/**/} 并无区别,例如下面两组代码所实现的功能是完全一致的。
struct Number{
private;
float val;
public:
float pubVal;
Number(float inVal);
};
class Number{
float val;
public:
float pubVal;
Number(float inVal);
};
所谓私有成员,就是外部函数不可访问的成员
void printPublic(Number num){
cout<<num.pubVal<<endl;
}
void printPrivate(Number num){
cout<<num.val<<endl; //报错,无法访问私有类型
}
不过从C语言的视角来看,类也的确保留了一些struct 的风格,其初始化方法与指针调用便是明证。
int main(){
Number num{3.14};
printNumber(num);
Number* pNum = #
cout<<pNum->pubVal<<endl;
system("pause");
return 0;
}
输出为
PS E:\Code\cpp> g++ .\oop.cpp
PS E:\Code\cpp> .\a.exe
3.14
3.14
2. explicit构造
由于C++对泛型具备十分良好的支持,语言本身的强大可能会导致用户在使用过程中不严谨,继而增大维护成本。例如对于如下构造函数
Number::Number(float inVal){
val = inVal;
}
那么下面的几个语句都能够输出正确的值
int main(){
Number num{3.14};
printNumber(num);
num = 1.414;
printNumber(num);
printNumber(0.618);
system("pause");
return 0;
}
结果为
PS E:\Code\cpp> g++ .\oop.cpp
PS E:\Code\cpp> .\a.exe
3.14
1.414
0.618
请按任意键继续. . .
可见这三条语句都没有报错
Number num{3.14};
num = 1.414;
printNumber(0.618);
第一条是没有问题的,是简单赋值语句;第二条和第三条则是暗中调用构造函数,将浮点类型的变量转换成了Number 类型,这种意义不明的代码自然会引起维护上的困难。explicit 就为解决这种问题而生的。
将构造函数用explicit 进行标记,可以有效禁止这种隐式转换
class Number{
float val;
public:
explicit Number(float inVal);
float pubVal;
};
int main(){
Number num{3.14};
num = 1.414;
printNumber(0.618);
}
3. const和mutable
顾名思义,二者分别是常量与变量,前者要求成员函数不得修改类的成员变量
class Number{
float val;
public:
mutable float pubVal;
explicit Number(float inVal);
void printVal() const;
};
void Number::printVal() const{
cout<<val<<endl;
pubVal = val+1;
}
即,const 成员只能修改mutable 成员。
4. 自引用
自引用是一种编程技巧,对于更改类状态的函数,如果将类本身作为返回值,那么就可以实现炫酷而优雅的链式操作。
class Number{
float val;
public:
explicit Number(float inVal);
Number& addOne();
};
Number& Number::addOne(){
cout<<val++<<endl;
return *this;
}
其中,*this 指向调用该成员函数的对象,测试一下
int main(){
Number num{3.14};
num.addOne().addOne().addOne();
system("pause");
return 0;
}
结果为
PS E:\Code\cpp> g++ .\oop.cpp
PS E:\Code\cpp> .\a.exe
3.14
4.14
5.14
请按任意键继续. . .
5. static
顾名思义,静态成员之所以被称为静态,在于其存储位置只有一个。对于一个类而言,无论创建了多少实例,类中的静态变量就只被存储在那一个位置。这意味着静态成员要比对象实例具有更长的生命周期,当一个对象被销毁之后,静态成员并没有被销毁,从而再次被调用的时候,也不必另行分配内存。
class Number{
float val;
static Number defaultNum;
public:
explicit Number(float inVal=0);
static void setDefault(float inVal);
void printVal() const;
};
void Number::printVal() const{
cout<<val<<endl;
}
Number Number::defaultNum{3.14};
void Number::setDefault(float val){
defaultNum = Number{val};
};
Number::Number(float inVal){
val = inVal ? inVal : defaultNum.val;
}
int main(){
Number num{};
num.printVal();
system("pause");
return 0;
}
输出为
PS E:\Code\cpp> .\a.exe
3.14
请按任意键继续. . .
复数的实现
复数有实部和虚部,默认值为0,其加法和减法分别就是实部和虚部相减,其乘法为
(a+bi)(c+di)=(ac−bd)+i(ad+bc)
除法为
c+dia+bi=c2+d2(a+bi)(c−di)=c2+d2ac+bd+c2+d2b
|