文章目录
一、C的struct和C++的类的区别
以下表格由DeepSeek-R1生成:
特性 | C 的 struct | C++ 的 struct | C++ 的 class |
---|---|---|---|
默认访问权限 | 无(仅数据) | public | private |
成员函数 | 不支持 | 支持 | 支持 |
继承/多态 | 不支持 | 支持 | 支持 |
构造/析构函数 | 不支持 | 支持 | 支持 |
模板 | 不支持 | 支持 | 支持 |
设计用途 | 纯数据聚合 | 简单数据+方法 | 封装复杂对象行为 |
实际开发中,C++ 的 struct 和 class 仅默认权限不同,但习惯上用 struct 表示数据为主的结构,class 表示具有复杂行为的对象。
- 在C中:
各种各样的函数的定义、struct - 在C++中:
实体(属性、行为) -> ADT(abstract data type)
对象 <-(实例化) 类(属性->成员变量行为->成员方法)
二、关于OOP
- Object Oriented Programming:面向对象程序设计
- OOP语言的四大特性:抽象、封装/隐藏、继承、多态
- 类中的访问限定符:(由DeepSeek-R1生成)
基类成员访问限定符 | 类内部访问 | 继承方式 | 派生类中基类成员的访问权限 | 外部代码访问 | 友元访问 |
---|---|---|---|---|---|
public |
✔ | public 继承 |
public |
✔ | ✔ |
protected 继承 |
protected |
✖ | ✔ | ||
private 继承 |
private |
✖ | ✔ | ||
protected |
✔ | public 继承 |
protected |
✖ | ✔ |
protected 继承 |
protected |
✖ | ✔ | ||
private 继承 |
private |
✖ | ✔ | ||
private |
✔ | 任何继承方式 | 不可访问 | ✖ | ✔ |
三、举例:一个商品类CGoods
#include <iostream>
using namespace std;
const int NAME_LEN = 20;
class CGoods {
public: // 给外部提供公有的成员方法,来访问私有的属性
// 商品数据初始化
void init(const char *name, double price, int amount);
// 打印商品信息
void show();
// 给成员变量提供getXXX或setXXX的方法(注意:类内部实现的方法,自动处理成inline内联函数)
void setName(const char *name) {
strcpy_s(_name, sizeof(_name), name); }
void setPrice(double price) {
_price = price; }
void setAmount(int amount) {
_amount = amount; }
const char *getName() {
return _name; }
double getPrice() {
return _price; }
int getAmount() {
return _amount; }
private:
char _name[NAME_LEN];
double _price;
int _amount;
};
void CGoods::init(const char *name, double price, int amount) {
strcpy_s(_name, sizeof(_name), name);
_price = price;
_amount = amount;
}
void CGoods::show() {
cout << "name: " << _name << endl;
cout << "price: " << _price << endl;
cout << "amount: " << _amount << endl;
}
int main() {
CGoods good1;
good1.init("面包", 10.0, 200);
good1.show();
good1.setPrice(20.5);
good1.setAmount(100);
good1.show();
CGoods good2;
good2.init("空调", 10000.0, 50);
good2.show();
return 0;
}
注意:
- 类可以定义无数个对象,每一个对象都有自己的成员变量,但是它们共享一套成员方法。
- 类内部实现的方法,自动处理成inline内联函数,外部则不会。
- 对象的内存大小,与成员变量有关。VS2022下可以通过cl C++面向对象.cpp /dlreportSingleClassLayoutCGoods查看占用内存大小。
- init(name,price,amount)怎么知道处理哪个对象的信息,把信息初始化给哪一个对象的呢?
类的成员方法一经编译,所有的方法参数,都会加一个this指针,接收调用该方法的对象的地址。
void init(CGoods *this, const char *name, double price, double amount);
void CGoods::init(CGoods *this, const char *name, double price, int amount) {
strcpy_s(this->_name, sizeof(this->_name), name);
this->_price = price;
this->_amount = amount;
}
init(&good1, "面包", 10.0, 200);
四、构造函数和析构函数
1、定义一个顺序栈
#include <iostream>
using namespace std;
const int NAME_LEN = 20;
class SeqStack {
public:
void init(int size = 10) {
_pstack = new int[size];
_top = -1;
_size = size;
}
void release() {
delete[]_pstack;
_pstack = nullptr;
}
void push(int val) {
if (full()) {
resize();
}
_pstack[++_top] = val;
}
void pop() {
if (empty()) {
return;
}
--_top;
}
int top() {
return _pstack[_top];
}
bool empty() {
return _top == -1; }
bool full() {
return _top == _size - 1; }
private:
int *_pstack;
int _top;
int _size;
void resize() {
int* ptmp = new int[_size * 2];
for (int i = 0; i < _size; ++i) {
ptmp[i] = _pstack[i];
} // memcpy(ptmp, _pstack, sizeof(int)*size);或realloc可能产生深拷贝浅拷贝的问题
delete[]_pstack;
_pstack = ptmp;
_size *= 2;
}
};
int main() {
SeqStack s;
s.init(5);
for (int i = 0; i < 15; ++i) {
s.push(rand() % 100);
}
while (!s.empty()) {
cout << s.top() << " ";
s.pop();
}