如何指定我在多重继承中派生的基类?

时间:2016-10-11 19:45:19

标签: c++ c++11 inheritance

我为我的编程课程做了一个功课,要求我设计一个摘要,从中派生两个类,并从这两个派生类派生另一个类。

这带来了致命的死亡钻石问题。这可以通过虚拟继承解决,但我需要将前两个类的对象实例化为我的抽象类的指针。这不能用任何类型的虚拟继承来完成。因此,如果有一种方法可以指定多重继承类将从中派生的基类,那么它将是天文学上有用的。

示例:

#include <iostream>

using namespace std;

class Base {
    public:
        virtual void foo(){};
        virtual void bar(){};
};

class Der1 : public Base {  
    public:
        virtual void foo();

};

void Der1::foo()
{
    cout << "Der1::foo()" << endl;
}

class Der2 : public Base {
    public:
        virtual void bar();
};

void Der2::bar()
{
        cout << "Der2::bar()" << endl;
}

class Join : virtual Der1, virtual Der2 {

    private:
        int atribb;



};

int main()
{
        Base* obj = new Join();
        ((Der1 *)(obj))->foo();
}

编译错误:

nueve.cpp:在函数'int main()'中:

nueve.cpp:43:30:错误:'基础'是'加入'的模糊基础

Base * obj = new Join();

2 个答案:

答案 0 :(得分:3)

使用虚拟继承。

let evenA = stride(from: 0, to: masterA.count, by: 2).map { masterA[$0] }
let oddA = stride(from: 1, to: masterA.count, by: 2).map { masterA[$0] }

如果在从基类派生时声明virtual,如下面的示例所示,则派生程度最高的类对象只包含一个基类子对象,这有助于解决案例中的歧义。 < / p>

在进行一些代码更改后,您的最终可执行代码:

以下示例中的代码更改:

在派生子类时添加了 vitual 关键字。 删除&#34;虚拟&#34;派生大多数派生类时的关键字。 修改main以正确调用成员函数。

import Swift

let N = 10_000_000
let RUNS = 50

let masterA = (0..<N).map { $0 }

var times = (0.0, 0.0, 0.0, 0.0)
for _ in 1...RUNS {

    // filter+map (dfri)
    do {
        let start = Date()
        let evenA = masterA.enumerated().filter { $0.0 % 2 == 0 }.map{ $0.1 }
        let oddA = masterA.enumerated().filter { $0.0 % 2 != 0 }.map{ $0.1 }
        let time = Date().timeIntervalSince(start)
        times.0 += time
    }

    // flatMap (dfri)
    do {
        let start = Date()
        let evenA = masterA.enumerated().flatMap { $0 % 2 == 0 ? $1 : nil }
        let oddA = masterA.enumerated().flatMap { $0 % 2 != 0 ? $1 : nil }
        let time = Date().timeIntervalSince(start)
        times.1 += time
    }

    // stride+map (me)
    do {
        let start = Date()
        let evenA = stride(from: 0, to: masterA.count, by: 2).map { masterA[$0] }
        let oddA = stride(from: 1, to: masterA.count, by: 2).map { masterA[$0] }
        let time = Date().timeIntervalSince(start)
        times.2 += time
    }

    // loop (Keiwan)
    do {
        let start = Date()
        var evenA = [Int]()
        var oddA = [Int]()

        for (index, element) in masterA.enumerated() {
            if index % 2 == 0 {
                evenA.append(element)
            } else {
                oddA.append(element)
            }
        }
        let time = Date().timeIntervalSince(start)
        times.3 += time
    }
}

print(N, RUNS)
print(times.0/Double(RUNS), times.1/Double(RUNS), times.2/Double(RUNS), times.3/Double(RUNS))

答案 1 :(得分:1)

目前还不清楚你要求的是什么,尽管你似乎在说Base的虚拟继承是不合适的。因此,假设这是正确的,您可以将Base* obj = new Join();替换为Base* obj = (Der1*)new Join();,并且您将获得指向Base对象的指针,该对象是Der1的基础。同样,您可以将其替换为Base* obj = (Der2*)new Join();,然后您将获得指向Base基础的Der2对象的指针。