C++ 在C++;,是否允许强制转换到只添加非虚拟方法的派生类?

C++ 在C++;,是否允许强制转换到只添加非虚拟方法的派生类?,c++,oop,inheritance,casting,C++,Oop,Inheritance,Casting,我想将非虚拟方法添加到无法更改的现有类A。因此,我创建了一个继承自a的类B,并添加了我想要的方法。现在,如果我有一个A类型的对象,我能把它看作B类型的对象吗?那么,以下代码是否合法 class A { <...> }; class B: public A { void f(); }; A a(); void g( const B& ); void h() { g( static_cast<B&&>(a()) ); } A类{};

我想将非虚拟方法添加到无法更改的现有类
A
。因此,我创建了一个继承自
a
的类
B
,并添加了我想要的方法。现在,如果我有一个
A
类型的对象,我能把它看作
B
类型的对象吗?那么,以下代码是否合法

class A { <...> };

class B: public A {
    void f();
  };

A a();
void g( const B& );
void h() { g( static_cast<B&&>(a()) ); }
A类{};
B类:公共A{
无效f();
};
A();
无效g(常数B&);
void h(){g(static_cast(a());}

它确实可以编译和工作,但是我想知道标准是否保证它能按预期工作。我不明白为什么不,但感觉不太干净。

这是未定义的行为。发件人:

“cv1 B”类型的左值(其中B是类类型)可以转换为“引用cv2 D”类型,其中D是类 如果存在从“指向D的指针”到“指向B的指针”的有效标准转换(4.10),则从B派生(第10条), cv2是与cv1相同或更高的cv资格,而B既不是虚拟基类 也不是D的虚拟基类的基类。结果的类型为“cv2 D”。类型为“cv1 B”的X值 可以强制转换为类型“cv2 D的右值引用”,约束条件与类型“cv1 B”的左值相同。 如果“cv1 B”类型的对象实际上是D类型对象的子对象,则结果引用封闭对象 类型为D的对象。否则,行为未定义。

a
实际上不是类型为
B
的对象的子对象-它实际上只是类型为
a
,因此行为未定义

如何阻止您简单地添加非成员函数:

void f(A& ); 

如果答案是您需要访问
A
private
protected
成员,那么您是有意让这些成员无法访问的

否,强制转换导致未定义的行为,但
B a
后接对函数的调用,该函数将
a&
作为参数,如
void foo(a&a)
和调用它是合法的并且是有定义的:
foo(a)
这样,在foo内部,如果你真的知道
a
实际上是
b
(但是你会怎么做呢?),你可以执行强制转换。为什么你想将一个对象强制转换成它不是的东西?@MikeMB:能够对它使用一个新方法,这在原始类中没有定义。或者重写现有方法。因此,您需要向对象
a
添加函数,而不更改该对象的实际类型,也不更改
a
的类定义。对吗?没有什么能阻止我,只是通过使用全局函数,我失去了OOP的一个优点。。太糟糕的是C++没有提供解决这个问题的方法。“AynoChanTalo”听起来更像是你发现了OOP的一个缺点。@ Ayon CohanTAL:在派生类中,你也不能访问一个基类的<代码>私下< /代码>部分。封装不会因派生而被破坏。@Yaron:这样会失去oop的什么好处?@Yaronchen-Tal这是一个关于oop的常见误解。见项目23。