• c++学习第十三


    1)循环引用的案例及解决办法:

    #include 
    #include 
    using  namespace std;
    class A;
    
    class B
    {
    public:
    	B(){cout<<"B constructor---"<<endl;}
    	~B(){cout<<"B deconstructor----"<<endl;}
    	std::weak_ptr<A> pA; //如果是std::shared_ptr,则会造成引用计数永远无法归0,资源不会被释放;
    };
    
    class A
    {
    public:
    	A(){cout<<"A constructor---------"<<endl;}
    	~A(){cout<<"A deconstructor----------------"<<endl;}
    	std::shared_ptr<B> pB;
    };
    
    int main()
    {
    	std::shared_ptr<A> pAA = make_shared<A>();
    	std::shared_ptr<B> pBB = make_shared<B>();
    	pAA->pB = pBB;
    	pBB->pA = pAA;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    2)emplace紧调用一次构造函数,push_back调用一次构造,一次拷贝,测试代码如下:
    所以:优先使用emplace成员函数。

    #include
    #include
    #include
    #include
    
    using namespace std;
    
    struct SBook
    {
    public:
    	SBook() : bookName(""), price(0)
    	{
    		std::cout << "default construct: " << bookName << std::endl;
    	}
     
    	SBook(std::string bookName_, int price_) : bookName(bookName_), price(price_)
    	{
    		std::cout << "construct: " << bookName << std::endl;
    	};
     
    	 SBook(const SBook& rhs) : bookName(rhs.bookName), price(rhs.price)
    	{
    		std::cout << "copy construct: " << bookName << std::endl;
    	}
     
    	~SBook()
    	{
    		std::cout << "deconstruct: " << bookName << std::endl;
    	}
     
    	bool operator <(const SBook& rhs) const
    	{
    		return bookName < rhs.bookName;
    	}
     
    public:
    	std::string bookName;
    	int price;
    };
     
    int main(int argc, char *argv[])
    {
     
    	// 测试vector
    	vector<SBook> books;
    	// 预先分配,否则整个vector在容量不够的情况下重新分配内存
    	books.reserve(100);
     
    	std::cout << "test push_back:" << endl;
    	books.push_back(SBook("C++从入门到放弃", 1));
    	std::cout << endl;
     
    	std::cout << "test emplace_back:" << endl;
    	books.emplace_back("水浒传", 2);
    	std::cout << endl;
     
    	std::cout << "test emplace_back default:" << endl;
    	books.emplace_back();
    	auto& book = books.back();
    	book.bookName = "红楼梦";
    	book.price = 5;
    	std::cout << endl;
     
    	std::cout << "test emplace:" << endl;
    	auto it = books.emplace(books.end());
    	it->bookName = "西游记";
    	it->price = 3;
    	std::cout << endl;
     
    	std::cout << "output all books: " << endl;
    	for_each(books.begin(), books.end(), [](const SBook& book)->void
    	{
    		std::cout << book.bookName << endl;
    	});
    	std::cout << endl;
     
     
    	// 测试set
    	set<SBook> bookSet;
     
    	std::cout << "test bookSet insert:" << endl;
    	bookSet.insert(SBook("十万个为什么", 1));
    	std::cout << endl;
     
    	std::cout << "test bookSet emplace:" << endl;
    	bookSet.emplace("新华字典", 2);
    	std::cout << endl;
     
    	std::cout << "output bookset: " << endl;
    	for_each(bookSet.begin(), bookSet.end(), [](const SBook&book)->void
    	{
    		std::cout << book.bookName << endl;
    	});
    	std::cout << endl;
            return 0 ;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96

    3)unordered_map的使用

    #include 
    #include 
    using  namespace std;
    
    template<class K,class V>
    using umap = std::unordered_map<K,V>;
    
    int main(void)
    {
    	umap<string,string> m{{"111","bbb"},{"222","ddd"}};
    	cout<<m["111"]<<endl;  //显示key为"111"的value;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4)利用模板类的参数,自动生成友元函数;
    芙蓉楼送辛渐
    王昌龄
    寒雨连江夜入吴,
    平明送客楚山孤。
    洛阳亲友如相问,
    一片冰心在玉壶;

    #include          // 包含头文件。
    using namespace std;        // 指定缺省的命名空间。
    
    template<class T1, class T2>
    class AA    
    {
        T1 m_x;
        T2 m_y;
    public:
        AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
        // 非模板友元:友元函数不是模板函数,而是利用模板类参数生成的函数,只能在类内实现。
      // 本质:编译器利用模板参数,帮我们生成了一个友元函数,但是这个函数不是模板函数
        friend void show(const AA<T1, T2>& a)
        {
            cout << "x = " << a.m_x << ", y = " << a.m_y << endl;
        }
    };
    
    int main(void)
    {
    	AA<int,string> a(44,"abcde");
    	show(a);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    5)模板类与函数的组合使用(包括:普通函数,函数模板特化版本,函数模板泛化版本)
    模板类可以用于函数的参数和返回值!

    #include          // 包含头文件。
    using namespace std;        // 指定缺省的命名空间。
    
    template<class T1, class T2>
    class AA    // 模板类AA。
    {
    public:
        T1 m_x;
        T2 m_y;
        AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
        void show() const { cout << "show()  x = " << m_x << ", y = " << m_y << endl; }
    };
    
    // 采用普通函数,参数和返回值是模板类AA的实例化版本。
    AA<int, string> func(AA<int, string>& aa)
    {
        aa.show();
        cout << "调用了func(AA &aa)普通函数。\n";
        return aa;
    }
    
    // 函数模板,参数和返回值是的模板类AA。
    template <typename T1,typename T2>
    AA<T1, T2> func(AA<T1, T2>& aa)
    {
        aa.show();
        cout << "调用了func(AA &aa)特化函数。\n";
        return aa;
    }
    
    // 函数模板,参数和返回值是任意类型。
    template <typename T>
    T func(T &aa)
    {
        aa.show();
        cout << "调用了func(AA &aa)任意类型泛化函数。\n";
        return aa;
    }
    
    int main()
    {
        AA<int, string> aa1(3, "我是一只傻傻鸟。"); //以上三个函数,优先调用普通函数,再次调用特化版本,最后是泛化版本!
        func(aa1);
    
    	AA<double,string> aa2(3.4,"5555"); //特化版本
    	func(aa2);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    6)模板类继承普通类范例:

    #include          // 包含头文件。
    using namespace std;        // 指定缺省的命名空间。
    class aa
    {
    public:
    	int a_;
    	aa(int a) :a_(a) { cout << "调用了AA的构造函数。\n"; }
    	void func1() { cout << "调用了func1()函数:m_a=" << a_ << endl;; }
    
    };
    
    template<class T1,class T2>
    class bb : public aa
    {
    public:
    	T1 x_;
    	T2 y_;	
    	bb(T1 x,T2 y,int a): aa(a),x_(x),y_(y){ cout << "调用了BB的构造函数"<<endl;}
    	void func2() const { cout << "调用了func2()函数:x = " << x_ << ", y = " << y_ << endl; }
    };
    
    int main(void)
    {
    	bb<int, string> bb(8, "我是一只傻傻鸟。",3);
    	bb.func2();
    	bb.func1();	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    学习知识tips:
    引用是指针常量的伪装
    构造函数一般有两个执行阶段:初始化阶段和赋值阶段;
    成员指针运算符 .* 或者 ->* c++特有的
    std::is_same //类型萃取相关的函数
    integral 美 [ˈɪntɪɡrəl] adj 完整的,n积分
    typeid跟sizeof用法意义,有两种写法 typeid(int);
    typeid(变量名或者表达式);

    7)匿名共用体一般是写在结构体中的

    #include          // 包含头文件。
    using namespace std;        // 指定缺省的命名空间。
    
    struct st_girl       // 定义超女结构体。
    {
    	int no;             // 超女编号。
    	union              // 定义匿名共同体udata。
    	{
    		int        a;
    		double b;
    		char     c[21];
    	};
    };
    
    int main()
    {
    	st_girl girl;
            cout<<sizeof(girl)<<endl; 
            //输出是32 = 4 + 4 + 24; 空的union占1个字节;那为什么4个呢,因为得字节对齐
            return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    8)共用体使用方法:

    #include          // 包含头文件。
    using namespace std;        // 指定缺省的命名空间。
    
    union udata         // 定义共同体udata。
    {
    	int        a;
    	double b;
    	char     c[21];
    };
    
    int main()
    {
    	udata data;
    
    	cout << "sizeof(data)="<< sizeof(data) << endl;
    
    	cout << "data.a的地址是:" << (void*) & data.a << endl;	//输出地址相同
    	cout << "data.b的地址是:" << (void*) & data.b << endl;//输出地址相同
    	cout << "data.c的地址是:" << (void*) & data.c << endl;//输出地址相同
    
    	data.b = 30; 
    	cout << "data.a=" << data.a << endl;
    	cout << "data.b=" << data.b << endl;
    	cout << "data.c=" << data.c << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    输出结果:
    sizeof(data)=24
    data.a的地址是:0x7ffd02aa4860
    data.b的地址是:0x7ffd02aa4860
    data.c的地址是:0x7ffd02aa4860
    data.a=0
    data.b=30
    data.c=

  • 相关阅读:
    ping 命令还能这么玩?
    智汇华云 | 华云软件定义网络 DCI介绍
    CSS盒子模型、列表样式
    cad转shp再转3dtiles生成白模
    Java Websocket 02: 原生模式通过 Websocket 传输文件
    论不使用除rsa之外的任何其他模块实现RSA加密解密,以及密钥存储
    技术分享 | 接口自动化测试如何处理 Header cookie
    PCycDB:全面准确的磷循环基因分析数据库
    案例 | 3D可视化工具HOOPS助力SolidWorks edrawings成功引入AR/VR技术
    探索Go语言在机器学习领域的应用局限与前景
  • 原文地址:https://blog.csdn.net/qq_30143193/article/details/132823381