命名空间
inline命名空间
inline声明的命名空间, 可以无视本层命名空间, 而可以被直接使用.
用处: 可以方便的变更版本, 如:
namespace libnet{
#include <version5.h>
#include <version4.h>
}
同时,
namespace libnet{
**inline** namespace version5{
........
}
}
namespace libnet{
namespace version4{
........
}
}
namespace使用的时候, libnet::默认使用的就是version5, 除非手动指定libnet::version4::
全局的inline的命名空间内的变量有可能导致和全局变量的命名冲突
如果实参中有一个是类, 那么编译器就会在整个函数名, 所有实参及函数内部默认使用了这个类的命名空间.
operator << (std::cin, string s)
<<其实是std::<<
string其实是std::string
一个类, 在查找其可用的函数的时候, 不仅在自己的作用域找, 还去基类的成员函数找, 还去基类的作用域中找. 如
namespace NS{
class Base{}
void display(Base ..){}
}
class Derived:public Ns::Base{};
int main()
{
Derived D;
display(D); // 调用display的时候, 不仅在当前作用域找, 还去基类的命名空间中查找
return 0 ;
}
虚继承
如果派生类D继承自两个不同的类d1, d2, 而恰好这两个类都继承自同一个类b, 那么??
因为在正常的继承关系中, 这两个类都持有各自的基类, 因此基类的成员会在D中有两个. 阻止方法是将d1 d2的继承方式声明为virtual.
class d1:virtual public b;
class d2:virtual public b;
虚继承声明了自己持有的基类的成员愿意是与其他类"共享的"
虚基类的继承关系是在项目组中一次性设计完成的, 后续独立开发者并不需要改变原有开发好的类的虚的实现. 一次性开发过程中, 声明为虚继承大多数也没有什么坏处
可见性: 如果d1或者d2中重新声明了一个b中存在的成员, 则在D中优先使用d中的成员(因为距离最近 最优), 如果两个都没声明, 就用b中. 如果两个都又声明了, 出错.
构造函数: D会直接初始化b. 派生类会直接初始化所有的虚基类. 因此, 当初始化一个派生类的时候, 编译器按照初始化顺序, 一个一个看是否有虚基类, 如果有, 则先把这个继承的虚基类初始化. 所有的虚基类都初始化完成后, 再去重头看, 按照原来的方式初始化所有的类.