自定义智能指针

使用模板类 重载 -> 操作符 重载 * 操作符 template<typename T> class MyAutoPtr{ public: MyAutoPtr(T * t){ ptr = t; } ~MyAutoPtr(){ if(ptr != NULL){ delete ptr; ptr = NULL; } } T* operator->(){ // 相当于 ptr-> , 所以返回 ptr 指针即可,将所有操作转发给真正的指针变量 return ptr; } T& operator*(){ // 相当于 (*ptr) ,所以返回 ptr 指向的对象引用即可 return *ptr; } private: T* ptr; }; class A{ public: A(int a){ cout << "A(int)..." << endl; this->a = a; } ~A(){ cout << "~A()....

January 4, 2022 · 1 min · Rick Cui

临时变量不能绑定 no-const 左值引用类型

error: cannot bind non-const lvalue reference of type ‘T&’ to an rvalue of type ‘T’ 如果一个参数是以非 const 引用传入,c++ 编译器就有理由认为程序员会在函数中修改这个值,并且这个被修改的引用在函数返回后要发挥作用。 但如果你 把一个临时变量当作非 const 引用参数传进来,由于临时变量的特殊性,程序员并不能操作临时变量,而且临时变量随时可能被释放掉。 所以,修改一个临时变量是毫无意义的。据此,c++ 编译器加入了临时变量不能作为非 const 引用的这个语义限制。 c++ 中临时变量是右值类型,不能取引用,只能在当前行使用,不能作为非 const 的引用参数 std::move() 返回的也是一个右值 对于临时变量或字面量的右值引用可以使用 cosnt & 或 && 类型的参数接收 一般来说,右值的地址不能通过解引用来获得,因为它们是字面量,或者因为它们本质上是临时的(例如由函数或显式构造函数调用返回的值)。通过将一个对象传递给这个函数,可以获得一个引用它的右值。 class T{ public: T(int v){ a = v; } T operator+(T &t){ T temp = this->a + t.a; return temp; } void printT(T &t){ cout << "a = " << t....

January 4, 2022 · 1 min · Rick Cui

操作符重载

还有类型转换函数 #include <iostream> using namespace std; class Complex{ // friend Complex complexAdd(Complex &c1, Complex &c2); // friend Complex operator+(Complex &c1, Complex &c2); // friend Complex& operator+= (Complex &c1, Complex &c2); friend ostream& operator<<(ostream &os, Complex &c); friend istream& operator>>(istream &is, Complex &c); public: Complex(){ cout << "Complex()..." << endl; a = 0; b = 0; } Complex(int a, int b){ cout << "Complex(int, int)..." << endl; this->a = a; this->b = b; } ~Complex(){ cout << "~Complex()....

January 3, 2022 · 4 min · Rick Cui

具有链表特性的类

买卖货物问题: #include <iostream> using namespace std; class Goods{ public: Goods(){ m_pNext = nullptr; m_weight = 0; cout << "买入了货物,重量是:" << m_weight << endl; } Goods(int weight){ m_pNext = nullptr; m_weight = weight; total_weight += m_weight; cout << "买入了货物,重量是:" << m_weight << endl; } ~Goods(){ total_weight -= m_weight; // m_pNext 不是在本类中 new 的,所以也不用 delete this->m_pNext = nullptr; cout << "卖出了货物,重量是:" << m_weight << endl; } static int getTotalWeight(){ return total_weight; } Goods *m_pNext; private: int m_weight; static int total_weight; }; int Goods::total_weight = 0; void buy(Goods *&head, int weight){ Goods *pNewGoods = new Goods(weight); if(head == nullptr){ head = pNewGoods; } else{ pNewGoods->m_pNext = head; head = pNewGoods; } } void sale(Goods *&head){ if(head == nullptr){ cout << "没有货物了" << endl; return; } Goods *temp = head; head = head->m_pNext; delete temp; temp = nullptr; } int main( ) { Goods *head = nullptr; int choice; do{ // 提供菜单 cout << "输入 1 进货" << endl; cout << "输入 2 出货" << endl; cout << "输入 0 退出" << endl; cin >> choice; switch(choice){ case 0: // 退出 return 0; case 1: { // 进货 int w = 0; cout << "输入货物重量:" << endl; cin >> w; buy(head, w); break; } case 2: // 出货 sale(head); break; } cout << "目前货物的总重量是:" << Goods::getTotalWeight() << endl; }while(1); return 0; } 输出:...

January 3, 2022 · 2 min · Rick Cui

new、delete 与内存

C++ 中 new 操作符内幕:new operator、operator new、placement new 1、new / delete 具体步骤 new 第一步:调用 operator new 函数分配一块足够大的,原始的,未命名的内存空间以便存储特定类型的对象 第二步:编译器运行相应的构造函数以构造对象,并为其传入初值 第三部:对象构造完成后,返回一个指向该对象的指针 delete 第一步:调用对象的析构函数 第二步:编译器调用 operator delete 函数释放内存空间 2、new/delete 与 malloc/free 的区别是什么? malloc/free 是 C 语言的标准库函数, new/delete 是 C++ 的运算符。它们都可用于申请动态内存和释放内存 malloc/free 不会去自动调用构造和析构函数,对于基本数据类型的对象而言,光用 malloc/free 无法满足动态对象的要求 malloc/free 需要指定分配内存的大小,而 new/delete 会自动计算所需内存大小 new 返回的是指定对象的指针,而 malloc 返回的是 void*,因此 malloc 的返回值一般都需要进行强制类型转换 operator new 重载: class Person{ public: Person(){ id = 0; score = 0; cout << "Person()" << endl; } Person(int id, int score):id(id),score(score){ cout << "Person(int, int)" << endl; } Person(const Person &p){ cout << "Person(const Person &p)" << endl; id = p....

December 29, 2021 · 2 min · Rick Cui