#pragma pack(1)
struct A
{
enum day{monring, moon, aftermoon};
};
sizeof(A) //1
sizeof(A::day) //4
为什么sizeof(A)为1,而sizeof(A::day)为4?
http://topic.csdn.net/u/20090323/17/7f78dfbd-8858-47af-acf4-68ffacdf9b30.html
1、基类指针指向派生类对象和派生类指针指向基类对象
在CoreJava 7 中提到C++中没有类似final的关键字,因此无法直接实现禁止类继承,但是 Cay S. Horstmann又说可以通过一些小技巧达到同样的效果,留作思考,但提示说用到虚基类。
究竟是如何的“技巧”呢,很惭愧,虚基类忘得快没影了,于是Google大神之,摘录如下:
下面的代码将会禁止继承:
class Lock {
friend class A;
private:
Lock() {}
};
class A : virtual public Lock {
//
public:
A(){}
A(int t){}
};
现在,如果你尝试从类A派生其它类将会得到类似下面这样的编译错误。
这是因为派生类都需要调用虚基类的构造函数,因此从A派生的B需要调用虚基类的构造函数(也就是Lock的构造函数),而Lock的构造函数是私有的,类B又不是Lock的友元,所以这将会产生一个编译错误。
如果我们移除类A派生时的virtual关键字,程序将会成功编译。这是因为在非虚拟继承中,任何类都可以调用直接父类中的构造函数。因此,在非虚拟继承中,B将调用它的直接父类A的构造函数而A将调用它的直接父类Lock的构造函数,这都是合法的。
3、inline和template
inline函数和templates两者通常都定义于头文件中。
inline函数通常一定被置于头文件内,因为大多数建置环境在编译过程中进行inline,而为了将一个“函数调用”替换为“被调用函数本体”,编译器必须知道那个函数长什么样子。
inlining在大多数C++程序中是编译期行为。
templates通常也被置于头文件内,因为它一旦被调用,编译器为了将它具化,需要知道它长什么样子。
templates的具现化与inlining无关。根据需要可将templates声明为inlined。
大部分编译器拒绝将太过复杂(例如带有循环或递归)的函数inlining,而所有对virtual函数的调用也都会是inlining落空。
因为virtual意味着“等待,知道运行期才确定调用哪个函数”,而inlining意味“执行前,先将调用动作替换为被调用函数的本体”。
编译器通常不对“通过函数指针而进行的调用”实施inlining。
inline void Fun()
{
cout<<"Hello World!"<<endl;
}
void (*pFun)() = Fun;
int main()
{
Fun(); //这个调用将被inlined,因为它是一个正常的调用
pFun(); //这个调用或许不被inlined,因为它通过函数指针完成
return 0;
}