三种显式上转换到私有基类的区别

Difference among three explicit upcasting to a private base class

本文关键字:基类 区别 转换 三种      更新时间:2023-10-16

在私有继承基类对象和子对象之间有以下三种类型转换,其中两种可以工作,但最后一种不行。我想知道是什么导致了不同的结果。

#include<iostream>
#include <string>
using namespace std;
class test :private string
{
public:
    test(string st) :string(st){}
    void show();
};
void test::show()
{
    cout << (string)*this << endl; // typecasting 1, works, display "abcd"
}
int main()
{
    test a("abcd");
    a.show();
    cout << (string &)a << endl; //typecasting 2, works, display "abcd"
    cout<<(string )a<<endl;   //typecasting 3;  error C2243: 'type cast' : conversion from 'test *' to 'const std::basic_string<char,std::char_traits<char>,std::allocator<char>> &' exists, but is inaccessible     
}

是不是a相同的'*this' -因为两者都是对象?那么为什么第一种方法有效呢?
如果是因为范围,那么为什么第二种方法有效?谁能解释一下它们背后的机制是什么?

同样,第一个方法似乎创建了一个字符串对象。在私有继承的情况下,基类引用不能设置为派生类对象。那么临时字符串对象是如何创建的呢?

test私下子类string,因此test"知道"它是string,但外部任何人都不知道。

在第一种情况下,发生的事情如下:

  1. test之外(在main中),您调用show方法。没关系,因为它是公开的。

  2. 现在,在show中,代码"知道"它的类型是string,因为它是test的一个方法。

但是,在第三种情况下,您试图在外部从main进行转换。在test之外,main"不知道"teststring

那么你的第二个案例是如何运作的呢?您正在执行从派生基到公共基的c风格强制转换。令人惊讶的是,这是允许的(尽管不一定是好的风格!)引自公认的答案:标准§5.4/7:

…即使基类类型不可访问,也可以使用显式类型转换的强制转换表示法执行下列static_cast和reinterpret_cast操作(可选地后跟const_cast操作):指向派生类类型对象的指针或派生类类型的左值可以分别显式转换为指向明确基类类型的指针或引用;