#创作计划# C++中的类与结构 2
2025-08-20 20:41:16
发布于:广东
Markdown源码4836字,渲染后实际字数4171字
是的没错因为上一篇没流量所以我滚过来继续更新了
前言
本文章介绍了C++中类的特性,包括运算符重载(特别鸣谢:@𝓬𝓱𝓮𝓷𝓰𝔀𝓶),继承,友元等。
类
运算符重载
现在有一个类A
,现在我们要将这个类的两个对象相加。
但是很明显,C++中并没有把+用于两个类A
的用法。这个时候,我们就需要使用运算符重载。
同样的,重载函数也需要是
public
。
A operator + (const A & other){//运算符重载
return i+other.i;
}
A operator + (const int & other){
return i+other;
}
正如代码里表示的,运算符重载也可以进行函数重载不是我这不是纯废话吗
这个时候,我们便可以这样使用+运算符:
A a(10);
A b(20);
A c = a + b;//c.i==30
c = c + 12;//c.i==42
同样的,也可以重载输入输出。
friend ostream& operator << (ostream& os,const A & other){
os << other.i;
return os;
}
//主函数
A a(12);
cout << a << endl;
输出12。
当运算符重载函数不在类中声明时,必须显式指定两个操作对象。
友元
各位可能注意到了,在上面的输出重载函数里,在函数定义的开头有一个friend
,而这个friend
的作用,就是将重载函数声明为这个类的友元函数。
友元函数
友元函数需要在类中该函数的原型前加上friend
,如:friend int func(int i);
。
虽然友元函数的原型在类中出现,然而它并不是类的成员函数。
友元类
声明一个类B
为另一个类A
的友元类,需要在类A
的定义中加入:friend class B;
。
此时,类B
的所有成员函数都是A
的友元函数。
友元函数没有
this
指针,需要看情况考虑是否将类传入为参数。
类访问修饰符
这段是临时加入的,作用是
防止被类的继承和多态肘死方便理解接下来的内容。
类的访问修饰符有三种:
public
private
protected
使用方法:
class A{
//private: C++类默认private
int i;
public:
int k;
A(int _i):i(_i),j(_i),k(_i){}
protected:
int j;
};
C++中的默认访问权限即为private。
public
(公有)修饰符
公有的成员在程序的外部也可以访问,如
int main(){
A a(12);
cout << a.k << endl;
cin >> a.k;
cout << a.k;
}
运行程序,首先输出12,输入后输出输入的数。
private
(私有)修饰符
私有成员只有类的成员和友元可以访问与操作。
如:
int main(){
A a(12);
cout << a.i << endl;
}
代码将会报错,提示i
是类A
的私有成员变量。
要输出i
,只能定义一个类的成员/友元函数:
void print(){
cout << i << endl;
}
然后将主函数更改为:
int main(){
A a(12);
//cout << a.i << endl;
a.print();
}
运行程序,输出12
。
protected
(受保护)修饰符
这个留到下面的继承讲,因为这个修饰符与继承有极大关联。
继承
基础
额,终于到了最痛苦的环节。
class A{
//private: C++类默认private
int i;
public:
int k;
A(int _i):i(_i),j(_i),k(_i){}
void print(){
cout << i << endl;
}
protected:
int j;
};
class B : public A{
public:
int l;
};
其中,类B
是派生类(子类),类A
是基类(父类)。
class B : public A
中的public
的作用是指定继承方式。
有三种继承方式,这三种继承方式会影响子类对父类的访问权限:
上方为继承方式,左侧为父类访问修饰符。
继承方式与访问修饰符 | public |
private |
protected |
---|---|---|---|
public |
public |
private |
protected |
private |
private |
private |
protected |
protected |
protected |
private |
protected |
但是,有两点不变:
private
成员只能被类内成员/友元访问,不能被派生类访问protected
成员可以被派生类访问
一般来说派生类继承基类的所有成员函数,但是以下基类的函数除外:
- 构造函数,析构函数,复制构造函数
- 重载运算符
- 友元函数
多继承
在C++中,一个派生类可以同时继承多个基类,这就是多继承。如:
class A{
//private: C++类默认private
int i;
public:
int k;
A(int _i):i(_i),j(_i),k(_i){}
void print(){
cout << i << endl;
}
protected:
int j;
};
class C{
public:
int ans;
C(int _a):ans(_a){
}
};
class B : public A,public C{
};
多个基类之间由逗号分隔。
多态
俺不行了脑子飞了
多态,按字面意思理解就是多种形态。
当类之间存在层级关系并且通过继承关联时,就会用到多态。
多态允许利用基类指针/引用来调用子类的重写方法,来使得同一接口可以表现出不同行为。
多态使得代码更加灵活、通用,程序可以通过基类指针/引用来操作不同的对象,而无需显式指定对象类型。
使用基类指针/引用调用派生类覆写函数的行为被称为动态绑定。
虚函数
C++中,多态是通过虚函数实现的。虚函数允许派生类重新定义函数,而派生类重新定义基类虚函数的行为被称为覆盖。
要定义一个虚函数,在函数的声明前加上virtual
。
程序实例:
#include<bits/stdc++.h>
using namespace std;
class A{
public:
virtual void print(){
cout << "classA\n";
}
};
class B : public A{
public:
void print(){
cout << "classB\n";
}
};
class C : public A{
public:
void print(){
cout << "classC\n";
}
};
int main(){
B b;
C c;
A* a;
a=&b;a->print();//将a指向b
a=&c;a->print();//将a指向c
}
运行结果
在这个栗子里,基类A
的函数print()
被声明为虚函数,可以在派生类B
,C
中重写。
纯虚函数
纯虚函数是一类特殊的虚函数,这类函数的定义部分用=0
代替,表示该函数为纯虚函数,没有主体。
例如:virtual void print()=0;
在有
=0
的情况下,仍然需要在声明中加入virtual
。
一个包含纯虚函数的类为抽象类,不能被直接实例化,同时会强制派生类提供该函数的具体实现。
多态的实现机制
- 虚函数表:每个包含虚函数的类都有一个虚函数表,存储了指向类中所有虚函数的指针。
- 虚函数指针:对象中包含一个指向该类虚函数表的指针。
注意事项
- 只有通过基类的指针/引用调用虚函数时才会发生多态。
- 多态需要运行时类型识别(RTTI),可能会显著增加代码的性能开销。
多态的优势
- 代码复用:通过基类指针/引用,可以调用不同派生类中覆写的虚函数,实现代码复用。
- 扩展性:新增派生类时,只需要确保派生类正确重写基类虚函数。
this
指针
让我们来一点轻松的内容,绝对不是因为我被继承和多态打傻了
在C++中,this
指针是一个特殊的指针,指向当前对象的实例,每一个对象都能通过this
指针访问自己的地址。
友元函数不是类的成员,因此没有
this
指针。
类的静态成员
对于类的一个成员,可以使用static
将其声明为静态的。当一个成员被声明为静态,无论创建多少个该类的对象,这个成员都只有一个,这个成员对于类的所有成员共享。
类的静态成员无法直接访问,但是可以通过运算符::
访问。
静态成员变量
如果没有初始化,类的静态成员变量默认初始化为0
。
静态成员变量必须显式初始化。
如:
#include<bits/stdc++.h>
using namespace std;
class A{
public:
static int count;//静态成员变量
A(){
++count;
cout << "创建新的A,计数" << count << endl;
}
};
int A::count = 0;
int main(){
A a;
A b;
A c;
cout << A::count;
}
输出:
静态成员函数
将类的成员函数声明为静态的,就可以把该成员函数和任何对象独立开。
静态成员函数在类的实例不存在的情况下也可以调用,只需要使用运算符::
。
静态成员函数没有this
指针,只能访问静态成员变量,其他静态成员函数。如:
#include<bits/stdc++.h>
using namespace std;
class A{
public:
static void print(){//静态成员函数
cout << "print" << endl;
}
};
int main(){
A::print();
}
附加篇-RTTI
其实这部分严格来说并不属于类,所以在此仅作简单解释。
RTTI(Run-Time Type Identification,运行时类型识别)允许程序在运行时动态确定对象类型,主要用于类的继承与多态。 (在努力敲键盘制作RTTI的科普了)
后记
参考资料太多,不写了。
整个C++中的类与结构到此结束,在老师视奸下写完这些东西的我真的很难,有错误请指出,觉得不错请支持一下。
这里空空如也
有帮助,赞一个