C++基础::拾遗&&琐碎
2015-11-17 23:03
218 查看
hpp vs cpp
hpp:类声明(declaration)cpp:类实现(definition)
拷贝构造存在的前提
忽然想到这么一个有意思的话题,拷贝构造(copy ctor)或者赋值构造(assignment ctor)存在的前提是存在一个别的什么构造比如默认构造或者一个含参数的构造,总之,你不能空手套白狼。异常会中断后续程序的进行
int main(int, char**) { try { throw std::exception("hello exception"); std::cout << "you cannot see me!" << std::endl; // 这句话不会被执行 } catch(std::exception& e) { std::cout << e.what() << std::endl; } return 0; }
default constructor
class A { public: A() { std::cout <<"A::A()" << std::endd;} }; class B { public: A _a; }; int main(int, char**) { B b; // 会在控制台界面打印"A::A()" // 证明默认构造函数会初始化每一位成员变量 return 0; }
要特别注意的是,初始化每一位成员变量用的是其成员变量自身的默认构造函数
class A { public: A(int) { cout << "A::A(int)" << endl;} // 显式提供给类一个构造函数之后, // 编译器会收回为它提供的那些默认构造函数(无参构造函数) } class B { private: A _a; } int main(int, char**) { B b; // 此时编译出错 // B的默认构造函数初始化其成员变量时,未找到其无参默认构造函数 return 0; }
编译器就是这么矫情,如果你提供了另外的构造函数,无论是含参的还是copy 构造或是赋值构造,它就不会在为你提供默认构造。
我们再来看一个更为典型的例子:
class Widget { public: Widget(){ cout << "Widget::Widget()" << endl;} } class Test { private: shared_ptr<Widget> _widget; public: shared_ptr<Widget> widget() { return _widget;} const shared_ptr<Widget> widget() const { return _widget;} } int main(int, char**) { Test t; // 什么也没有输出 // t的默认构造函数会初始化会分别调用其成员函数的默认构造函数 // shared_ptr<Widget>对象类型的默认构造函数不仅不会调用 // Widget的默认构造函数,而且是什么也不做,这一点可参阅其源码 return 0; }
这就牵涉到智能指针对象的构造问题了,调用一个其默认构造函数什么工作也不会做,只有当拷贝构造,或者赋值构造发生时,才会进行真正的构造工作:
int main(int, char**) { Test t; shared_ptr<Widget> w(new Widget); t.widget() = w; return 0; }
friend
一个类内部的有友元函数声明不是类内部的一部分,因此不受访问修饰的影响,放在一个类声明的任何位置都是等效的。继承关系中的父类的虚函数
继承关系中的父类的非纯虚函数要给出实现。class Base { public: void foo(); // 可以不给出实现,但当调用Base对象(如果Base不是抽象基类)的foo函数时才会发生解析错误 virtual void fooA(){} // 只有派生类A才能使用的接口 virtual void fooB(){} // 只有派生类B才能使用的接口 virtual void func() = 0; // 子类必须提供该纯虚函数的实现方可进行实例化 }; class DerivedA :public Base { public: void fooA() {} void func() {} } class DeriveB :public Base { public: void fooB() {} void func() {} } int main(int, char**) { DerivedA da; DerivedB db; da.foo(); // 访问基类中的foo(),前提是Base提供实现 da.fooA(); da.fooB(); return 0; }
相关文章推荐
- 和尚特烦恼3——何时能下山
- 和尚特烦恼2——第几个素数
- 《C++ Primer》学习笔记:习题9.39 string对象中单词统计
- C++ Primer Plus(第五版)第五章编程练习题6(关于string难点哦)
- C++ 怎么在默认构造函数的初始化列表中初始化指针或者引用类型数据成员
- 和尚特烦恼1——是不是素数
- C++primer习题3.14 vector<string>读写字符
- 和尚特烦恼1——是不是素数
- C++程序习题-将字符串按逆序输出[1.15]
- C++经典面试题之---String类
- C++面试题(二)——自己实现一个String类
- C++面试题(四)——智能指针的原理和实现
- C++面试题(一)——基础概念篇
- 【学习笔记】 关键字:字符串,strlen
- 对C++中异常接口声明的认识
- gedit C语言 配置
- 今日学习札记——STL常用容器:vector、list、set和multiset、map和multimap(11.17)
- 图像处理提取图像的奇数行列-学习笔记1
- C/C++编程题之判断字符串子串
- 第一章c语言概述