您的位置:首页 > 运维架构 > 网站架构

利用LVS+Keepalived 实现高性能高可用负载均衡

2012-09-18 10:46 736 查看
C风格的强制转换在C++依然能用,但是C++鼓励程序员采用新风格的强制转换,即四种cast。const_cast主要用于处理const修饰,和其他几种有很大区别,因此不容易混淆。因此主要记录另外三种cast,不准确,但是便于记忆。

1. static_cast

普通的强制转换,基类<-->派生类,int <--> double等等。遵循C的隐式转换规则。

2. reinterpret_cast

最为接近C风格的强制转换,在static_cast基础上支持更宽松类型转换,比如可以把指针类型转换为int类型。

3. dynamic_cast

最为严格的强制转换,只能进行指针或者引用类型转换,而且要求满足转换安全。即只允许派生类类型向基类类型转换,否则抛出异常。

结合类的派生,考察以下程序

#include <iostream>

using namespace std;

class base
{
public:
base(){cout << "Construct Base\n";}
virtual void print(){cout << "Base\n";}
};

class derive : public base
{
public:
derive(){cout << "Construct Derive\n";}
void print(){cout <<"derive\n"; }
};

int main()
{
derive dl;
(static_cast<base> (dl)).print(); // "Base"
(static_cast<base&> (dl)).print(); // "derive"
derive * dp = new derive;
//cout << (static_cast<int> (dp));   // 无法从“derive *”转换为“int”
cout <<(reinterpret_cast<int>(dp)) << endl;
(reinterpret_cast<base*> (dp))->print();
delete dp;

while(1);
return 0;
}

不难看出, static_cast是不能把指针类型转为整型,但是reinterpret_cast可以。我们可以理解为,reinterpret_cast是进行的内存级别的转换。

但是,其中有个蹊跷的地方,为什么static_cast做普通类型转换,调用的是基类的函数,难道是不查询虚表了吗?于是,我们进行下面的尝试:

#include <iostream>
using namespace std;

class base
{
public:
base(){cout << "Construct Base\n";}
virtual void print(){cout << "Base\n";}
};

class derive : public base
{
public:
derive(){cout << "Construct Derive\n";}
void print(){cout <<"derive\n"; }
};

int main()
{
derive dl;
cout << (reinterpret_cast <int> (&dl)) << endl;
cout << reinterpret_cast <int> (& static_cast<base>(dl)) << endl;
cout << reinterpret_cast <int> (& static_cast<base&> (dl)) << endl;
while(1);
return 0;
}

执行结果:

Construct Base
Construct Derive
3079920
3079716
3079920

所以,虚表一样查询了,但是由于不是引用类型的转换,编译器重新生成了基类的实例。因此,查询的是基类的虚表而不是派生类的。

但是,这里生成的新实例,是按位复制的。那么是因为我们没有定义复制构造函数,还是编译器底层做的复制呢?给两个类添加复制构造函数,继续实验。

#include <iostream>
using namespace std;
class base
{
public:
base(){cout << "Construct Base\n";}
base(const base& b){cout << "Copy construct\n";}
virtual void print(){cout << "Base\n";}
};

class derive : public base
{
public:
derive(){cout << "Construct Derive\n";}
derive(const derive& d){cout << "Derive copy construct";}
void print(){cout <<"derive\n"; }
};

int main()
{
derive dl;
cout << (reinterpret_cast <int> (&dl)) << endl;
cout << reinterpret_cast <int> (& static_cast<base>(dl)) << endl;
cout << reinterpret_cast <int> (& static_cast<base&> (dl)) << endl;
while(1);
return 0;
}

执行结果:

Construct Base
Construct Derive
1505236
Copy construct
1505032
1505236

Bingo! 又让我猜中了,吼吼~因为是基类的对象,调用的只是基类的复制构造函数,把待类型转换的对象复制了一份基类的引用。

如果使用dynamic_cast就没有这么多问题了,因为只能转换指针和引用类型,不会构造新的对象。
本文出自 “新青年” 博客,请务必保留此出处http://luckybins.blog.51cto.com/786164/995125
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: