我在一个容器中存储了一个指向一组异构对象的指针列表,使用一个字符串来标识它们。关于这次行动的安全性,我已经在这里讨论过了,我没意见。
问题是,当类有多重继承,并且我试图将同一个指针转换到一个或另一个超类时,第二次转换似乎会失败。
下面是一个示例:
#include <iostream>
#include <map>
using namespace std;
class A {
public:
virtual void hello() = 0;
};
class B {
public:
virtual void goodbye() = 0;
};
class C : public A,
public B
{
public:
void hello() override {
std::cout << "C says: Hello World!" << std::endl;
}
void goodbye() override {
std::cout << "C says: GoodBye World!" << std::endl;
}
};
class D : public A {
public:
void hello() override {
std::cout << "D says: Hello World!" << std::endl;
}
};
class E : public B {
public:
void goodbye() override {
std::cout << "E says: GoodBye World!" << std::endl;
}
};
int main()
{
std::map <std::string, void*> mymap;
C c;
D d;
E e;
mymap["C"] = (void*) &c;
mymap["D"] = (void*) &d;
mymap["E"] = (void*) &e;
static_cast<A*>(mymap["D"])->hello();
static_cast<B*>(mymap["E"])->goodbye();
static_cast<A*>(mymap["C"])->hello();
static_cast<B*>(mymap["C"])->goodbye();
return 0;
}
预期产出将是:
D says: Hello World!
E says: GoodBye World!
C says: Hello World!
C says: GoodBye World!
但我得到的却是:
D says: Hello World!
E says: GoodBye World!
C says: Hello World!
C says: Hello World!
我什至不知道这怎么可能,因为我什至没有打招呼
。
编辑在理解了这个页面的副本中讨论的内容后,我最终得到了这个解决方案:
int main()
{
std::map <std::string, void*> mymap;
C c;
D d;
E e;
mymap["C"] = static_cast<A*>(&c);
mymap["D"] = static_cast<A*>(&d);
mymap["E"] = static_cast<B*>(&e);
static_cast<A*>(mymap["D"])->hello();
static_cast<B*>(mymap["E"])->goodbye();
static_cast<A*>(mymap["C"])->hello();
dynamic_cast<B*>(static_cast<A*>(mymap["C"]))->goodbye();
return 0;
}
我发现的另一种解决方案也是使第二个类继承前一个类:
...
class B : public A{
public:
virtual void goodbye() = 0;
};
class C : public B
{
public:
void hello() override {
std::cout << "C says: Hello World!" << std::endl;
}
void goodbye() override {
std::cout << "C says: GoodBye World!" << std::endl;
}
};
...
int main()
{
std::map <std::string, void*> mymap;
C c;
D d;
mymap["C"] = static_cast<A*>(&c);
mymap["D"] = static_cast<A*>(&d);
static_cast<A*>(mymap["D"])->hello();
static_cast<A*>(mymap["C"])->hello();
dynamic_cast<B*>(static_cast<A*>(mymap["C"]))->goodbye();
return 0;
}
您的代码具有未定义的行为。
给定一个转换成< code>B*的< code>void*,计算机没有办法知道< code>B子对象在哪里(在实际上是< code>C的指向对象中)。你只是假装整个东西(或者,至少,它的前缀)是一个< code>B,如果它是一个简单的单一继承,这将是正确的…但是你的不是;第一垒是一个< code>A,不是一个< code>B。
不要像这样擦除带有 void*
的类型。
问题内容: 假设我有多个继承方案: 有编写的两个典型方法的: (老式) (较新的样式) 但是,无论哪种情况,如果父类(和)没有遵循相同的约定,则代码将无法正常工作(某些代码可能会丢失,或被多次调用)。 那么又是什么正确的方法呢?说“保持一致,遵循一个或另一个”很容易,但是如果或来自第三方图书馆,那又如何呢?有没有一种方法可以确保所有父类构造函数都被调用(以正确的顺序,并且只能调用一次)? 编辑:看
问题内容: 假设我有以下两个课程 如果我启动一个beta类型的新对象,如何执行在alpha类而不是beta中找到的逻辑?我可以使用<-我想知道是否可行。 Eclipse IDE中的自动键入功能使我可以选择从class 或class中进行选择。 问题答案: 你可以做: 注意,这是对父级的引用,但是super()是它的构造函数。
超类 子类
我想在更深层次的继承中为一个类实现构建器模式,其中一些字段是强制性的(message,case),而一些字段是可选的(myOptField1,MyOptField2…)通过使用Lombok@Builder并假设父类不能更改。因此,我实现了自己的builder(),如下所示: 那么这个类的使用方式可以是: 在IntelliJ的想法中,一切似乎都很好,但我得到了编译错误: 因此编译器只能看到由Lomb
假设我有一个继承链,其中每个类都通过添加一个新字段来扩展其超类,我希望该链的每个类都覆盖方法,如下所示: 如果我使用抽象基类,那么当继承链的一个类通过实现抽象方法变得具体时,从那时起的所有子类也通过继承已经实现的方法变得具体。 Java中有没有一种方法可以强制每个类重写(重新实现)抽象方法,即使它已经在继承链中实现得更高?
您可以看到,我正在将“that”作为参数传递给PrintInfo。如果没有“that”参数,“info”将打印为“undefined”。像下面的例子一样,当从“子类”的对象调用此函数时,“this.info”是未定义的。 如何在javascript中重写和调用超类的方法,使函数能够访问类的实例变量?