企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# C++基础 ## 友元函数 友元类 ~~~ 权访问类的所有私有(private)成员和保护(protected)成员 class Box { double width; public: double length; friend void printWidth( Box box ); void setWidth( double wid ); }; friend class ClassTwo; ~~~ ## 类 ~~~cpp //public 类外部可以访问 //protected 子类可以访问,外部不能访问 //private 只能本类访问 //delete 删除该类型函数,程序中不可调用,调用会报错 //defaulte 指定默认构造函数 //explicite 防止类构造函数的隐式自动转换 //final 终结虚函数传递, 子类不能再实现该函数 只能用于虚函数 //override 说明该函数式覆盖函数,父类必须有其相同定义, 只能用于虚函数 class FirstClass { public: virtual int getLength( void ); FirstClass (bool ) = delete; FirstClass (char ) = default; explicite FirstClass ( int len ); // 简单的构造函数 FirstClass ( const Line &obj); // 拷贝构造函数 ~FirstClass (); // 析构函数 virtual void vir_fun(); //虚函数 类多态使用 virtual int area() = 0; //不用给出实现 派生类必须实现 protected: private: } //继承 //public 保持之类的访问属性 即: public protected private //protected 改变继承的 public访问控制位 protected,其他不变 //private 改变继承的 protected public为 private //子类只能访问父类 protected public的成员不能访问 private的成员 class ChildClass : public FirstClass{ using FirstClass::FirstClass; final void vir_fun() {} final int area() {} virtual int getLength()override {} } //多态 FirstClass *firstClass = (new ChildClass(5)); firstClass->vir_fun() //执行ChildClass类的函数 ~~~ ## 重载操作符 ~~~ 可以被重载的操作符:new,new[],delete,delete[],+,-,*,/,%,^,&,|,~,!,=,<,>,+=,<<,>>,<<=,>>=,++,!=,<=,>=,&&,||,++,--,->*,->,(),[] 不可以被重载的操作符:. .* :: ?: class UPInt { // "unlimited precision int" public:  UPInt& operator++(); // ++ 前缀  const UPInt operator++(int); // ++ 后缀  UPInt& operator--(); // -- 前缀  const UPInt operator--(int); // -- 后缀  UPInt& operator+=(int); // += 操作符,UPInts  // 与ints 相运算  ... }; ~~~ ## ## 强类型枚举 enum class ~~~ enum class Direction { Left, Right }; enum class Answer { Right, Wrong }; enum class Answer : unsigned long { } auto a = Direction::Left; auto b = Answer::Right; if (a == b) std::cout << "a == b" << std::endl; else std::cout << "a != b" << std::endl; ~~~ ## 静态断言 static assert ~~~ static_assert( size_of(int) == 4 ); ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 构造函数的相互调用 delegating constructor ~~~ class A { public: A(int x, int y, const std::string& name) : x(x), y(y), name(name) { if (x < 0 || y < 0) throw std::runtime_error("invalid coordination"); if (name.empty()) throw std::runtime_error("empty name"); } A(int x, int y) : A(x, y, "A") {} A() : A(0, 0) {} private: int x; int y; std::string name; }; ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## constexpr常量表达式 ~~~ constexpr 用于向编译器指出,常量表达式 constexpr int a = 20; /* 20 是常量表达式 */ constexpr int b = a + 2; /* a + 2 是常量表达式 */ ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## \*\*override 和 final \*\*虚函数 ~~~ override  修饰函数, 函数必须覆盖父类的函数,      final 打断virtual的传播 如果一个虚函数被final修饰所有的子类都不能覆盖该函数, ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 默认构造函数 default ~~~ class A { public: A(int i) {} A() = default; }; ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 删除构造函数 delete ~~~ class A { public: A() = delete; }; ~~~ ## lambad ~~~ Lambda 表达式: Lambda表达式就是匿名函数,。 [capture](parameter)mutable -> return-type{state} capture 是捕捉列表。 parameter 是参数列表,就是函数的那些传入变量。 mutable 这个后面再介绍。 return-type 返回值的类型,如果返回值明确,也可以省略。 state 是函数体 Lambad 表达式引入符: [] 不捕获任何局部变量 [=] 以传值的方式捕获外部变量 [&] 以引用的方式捕获外部变量 [x, &y] x传值捕获, y引用捕获 [=, &x] x引用捕获, 其他传值捕获 [&, x] x传值捕获, 其它引用捕获 [a, &str]->QString{} 传值捕获a, 引用捕获str, 返回值是QString。 ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## ## 智能指针 ~~~ //std::auto_ptr 指针对象析构 指向对象自动释放 auto item = auto_ptr<Item> (new Item()); auto_ptr复制构造函数中把真是引用的内存指针进行的转移 可能产生野指针 //std::shared_ptr shared_ptr自动销毁所管理的对象 std::shared_ptr 是一种智能指针,它能够记录多少个 shared_ptr 共同指向一个对象,从而消除显示的调用 delete,当引用计数变为零的时候就会将对象自动删除。 std::shared_ptr 可以通过 get() 方法来获取原始指针,通过 reset() 来减少一个引用计数,并通过get_count()来查看一个对象的引用计数。 shared_ptr<int> p1; //被初始化成为一个空指针 shared_ptr<int> p2 (new int(4)); //指向一个值是4的int类型数据 shared_ptr<int> p3 = new int(4); //错误,必须直接初始化 shared_ptr<T> p; //空智能指针,可指向类型是T的对象 if(p)  //如果p指向一个对象,则是true (*p) //解引用获取指针所指向的对象 p -> number == (*p).number; p.get(); //返回p中保存的指针 swap(p,q); //交换p q指针 p.swap(q); //交换p,q指针 make_shared<T>(args)  //返回一个shared_ptr的对象,指向一个动态类型分配为T的对象,用args初始化这个T对象 shared_ptr<T> p(q) //p 是q的拷贝,q的计数器++,这个的使用前提是q的类型能够转化成是T* shared_pts<T> p(q,d)  //p是q的拷贝,p将用可调用对象d代替delete //上面这个我其实没懂,也没有查出来这个的意思 p =q; //p的引用计数-1,q的+1,p为零释放所管理的内存 p.unique(); //判断引用计数是否是1,是,返回true p.use_count(); //返回和p共享对象的智能指针数量 p.reset(); p.reset(q); p.reset(q,d); //reset()重新设置 新的指想对象 //std::weak_ptr weak_ptr是一种不控制所指向对象生存期的智能指针,指向shared_ptr管理的对象,但是不影响shared_ptr的引用计数。它像shared_ptr的助手,一旦最后一个shared_ptr被销毁,对象就被释放,weak_ptr不影响这个过程。 weak_ptr是为配合shared_ptr而引入的一种智能指针来协助shared_ptr工作,它可以从一个shared_ptr或另一个weak_ptr对象构造,它的构造和析构不会引起引用计数的增加或减少。没有重载 * 和 -> 但我们可以通过lock来获得一个shared_ptr对象来对资源进行使用,如果引用的资源已经释放,lock()函数将返回一个存储空指针的shared_ptr。 expired函数用来判断资源是否失效。 weak_ptr的使用更为复杂一点,它可以指向shared_ptr指针指向的对象内存,却并不拥有该内存,而使用weak_ptr成员lock,则可返回其指向内存的一个share_ptr对象,且在所指对象内存已经无效时,返回指针空值nullptr。 注意:weak_ptr并不拥有资源的所有权,所以不能直接使用资源。 可以从一个weak_ptr构造一个shared_ptr以取得共享资源的所有权。 weak_ptr<T> w(sp); //定义一个和shared_ptr sp指向相同对象的weak_ptr w,T必须能转化成sp指向的类型 w = p; //p是shared_ptr或者weak_ptr,w和p共享对象 w.reset(); //w置为空 w.use_count(); //计算与w共享对象的shared_ptr个数 w.expired(); //w.use_count()为0,返回true w.lock(); //w.expired()为true,返回空shared_ptr,否则返回w指向对象的shared_ptr share_ptr<X> pnew(w.lock()) //std::unique_ptr unique_ptr 不共享它的指针。它无法复制到其他 unique_ptr,无法通过值传递到函数,也无法用于需要副本的任何标准模板库 (STL) 算法。只能移动unique_ptr。 可以使用 移动语义转移所有权 unique_ptr<int> pInt(new int(5)); unique_ptr<int> pInt2 = std::move(pInt); // 转移所有权 转换为右值 函数可以返回 unique_ptr 类似移动语义 函数返回值是右值 unique_ptr<int> clone(int p) { unique_ptr<int> pInt(new int(p)); return pInt; // 返回unique_ptr } int main() { int p = 5; unique_ptr<int> ret = clone(p); cout << *ret << endl; } //示例代码 #include <memory> #include <iostream> #include <utility> class Foo{ public: Foo() = default; Foo(int a):_a(a) {} ~Foo() {} int get_a(){ return _a; } void set_a(int a) { _a = a; } private: int _a; }; std::unique_ptr<Foo> change_a(std::unique_ptr<Foo> f) { f->set_a(10); return f; } int main() { // std::make_unique是c++14才有 std::unique_ptr<Foo> pf = std::make_unique<Foo>(10); // unique_ptr的复制构造函数和拷贝构造函数是删除了的,这样保证了对象独占,如果不是独占,那么跟shared_ptr // 就是一样的功能了。 // std::unique_ptr<Foo> pf1 = pf; // compile error // 按值传参,会有拷贝问题,同上 // auto p = change_a(pf); //compile error auto p = change_a(std::move(pf)); std::cout << "get_a = " << p->get_a() << std::endl; if(!pf) { std::cout << "pf is nullptr" << std::endl; } //owner transfer from function std::unique_ptr<Foo> pf2 = std::make_unique<Foo>(11); std::unique_ptr<Foo> p2 = change_a(std::move(pf2)); std::cout << "get_a = " << p2->get_a() << std::endl; if(!pf2) { std::cout << "pf2 is nullptr" << std::endl; } //使用reset pf2.reset(new Foo(12)); std::cout << "pf2 is not null: " << pf2->get_a() << std::endl; //release获取原始指针 Foo* ff = pf2.release(); if(!pf2) { std::cout << "pf2 is nullptr" << std::endl; } std::cout << "ff is not null: " << ff->get_a() << std::endl; return 0; } ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 智能指针数组删除 ~~~ //! shared_ptr std::shared_ptr<int> p(new int[10],std::default_delete<int[]>());  //! unique_ptr std::unique_ptr<int[]> p(new int[10]);//ok auto value = make_unique<int[]>(5); auto value = shared_ptr<Employee[]>(new Employee[5]); c++ 17开始 auto value = shared_ptr<Employee[]>(new Employee[5]{0, 1, 2, 3, 4}); ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## ## ## ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)