初始化派生类的成员 (C++)
初始化从基类转换而来的派生类的首选方法是什么?
考虑以下场景:
class A{
public:
A();
~A();
}
class B : public A{
public:
B() {m_b = 0.0;};
~B();
float GetValue(){return m_b;};
private:
float m_b;
}
A* a = new A;
B* b = static_cast<B*>(a);
float val = b->GetValue(); // This was never initialized because it was not constructed
我当前的解决方案是手动调用 Initialize() 函数,该函数将像构造函数一样执行必要的初始化。
虽然看起来很草率,但必须有更好/更干净的方法。
非常感谢任何帮助和指导!
What is the preferred method for initializing a derived class that was casted from it's base class?
Consider the following scenario:
class A{
public:
A();
~A();
}
class B : public A{
public:
B() {m_b = 0.0;};
~B();
float GetValue(){return m_b;};
private:
float m_b;
}
A* a = new A;
B* b = static_cast<B*>(a);
float val = b->GetValue(); // This was never initialized because it was not constructed
My current solution is to manually call an Initialize() function which would perform the necessary initializations as the constructor would.
It seems sloppy though and there must be a better/cleaner method.
Any help and guidance is greatly appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这是一个错误的构造:
编辑
它实际上应该是:
因为,正如 sbi 指出的那样,A 没有名为 GetValue() 的虚拟函数,因此永远不能从 A 调用它。
不要这样做从 A* 到 B* 的 static_cast。
This is a faulty construct:
EDIT
It should really be:
Since, as sbi pointed out, A does not have a virtual function called GetValue(), so it can never be invoked from A.
Do not do a static_cast from A* to B*.
您正在将父对象转换为派生类型的对象。这完全是错误的。 A 类的对象没有要初始化的 m_b 成员。
You are casting a parent object into an object of a derived type. That is plain wrong. An object of class A does not have an m_b member to initialise.
我不确定这是否有效,因为该对象是使用
sizeof(A)
创建的,而sizeof(B)
显然更大。I'm not sure this is valid at all, because the object was created with
sizeof(A)
andsizeof(B)
is clearly larger.您没有要初始化的派生类的实例 - 您只有基类的实例。 1static_cast1 所做的只是强制编译器允许您将基类视为派生类。
相反,要创建一个
B
,您应该这样做:这将调用
B
的构造函数,将m_b
初始化为0.0
。You don't have an instance of the derived class to initialize - you only have an instance of the base class. All the 1static_cast1 is doing is forcing the compiler to allow you to treat the base class as a derived class.
Instead, to create a
B
, you should be doing is this:That will call the constructor of
B
, initializingm_b
to0.0
.您描述的代码是危险且无效的,因为 B 是 A,但反之则不然。这将是有效的:
The code you described is dangerous and not valid, since B is A, but not the other way around. This would be valid:
仅当您知道
a
实际上指向B
的对象或从B< 派生的类时,才应使用
static_cast
。 /code>,显然不是这样的。这是一个错误的说法。
有效序列应该是:
a
现在指向B
类型的对象。之所以可以这样做,是因为指向基类对象的指针始终可以指向派生类的对象,只要它是公共派生。现在,您可以使用
static_cast
因为您确信a
实际上指向B 类
的对象。在某些情况下,人们不知道类的层次结构,并且在这种情况下无法使用
static_cast
C++ 在这种情况下提供了另一种名为Dynamic_cast
的强制转换类型,它将如果在指针的情况下强制转换无效,则返回空指针,或者在引用的情况下抛出异常。需要注意的是,
Dynamic_Cast
仅适用于多态类。You should be using
static_cast
this only if you know thata
actually points to an object ofB
or a class derived fromB
, which is clearly not the case.It is an incorrect statement.
The valid sequence should be:
a
now points to a object of the typeB
. It can do so because Pointer to the object of Base class can always point to the objects of the derived class, as long as it is a public derivation.Now, you can use
static_cast
because you know for sure thata
actually points to object ofclass B
.There can be scenarios where in one is not aware of the hierarchy of classes and in such scenarios one cannot use
static_cast
C++ provides another cast type calledDynamic_cast
in such scenarios, it will return a null pointer if the cast is not valid in case of pointers or throw an exception in case of references.Point to note though
Dynamic_Cast
works only with polymorphic classes.