假设我有一些类:Base、Derived1、Derived2、...etc。所有派生类都是从Base派生的。现在,我想为所有派生类添加一些功能,但是这些类不能被修改。因此,我想出了以下方法:
使用以下虚拟继承创建一个类Additional:
class Additional: virtual public Base {
void f() {
//some codes operating on class Base
}
};
然后,我可以以这种方式扩展每个派生类:
class MyDerived1: public Derived1, public Addition
我有一个关于虚拟基类的问题。为了解决多重继承中“可怕的死亡钻石”的/ambiguity问题,引入了虚拟基类。
class A { public: void Foo() {} };
class B : public virtual A {};
class C : public virtual A {};
class D : public B, public C {};
如果在class C声明中不使用关键字virtual,会发生什么情况。你能给我详细解释一下吗?
class A { public: void Foo() {} };
class B : public virtual A {};
c
这还能解决钻石问题吗?
class A
{};
class B : virtual A
{};
class C : A
{};
class D : B, C
{};
编辑:,如果不是,那是什么?和这个一样吗?
class A
{};
class B : A
{};
class C : A
{};
class D : B, C
{};
或者是别的什么东西?
我经常使用纯虚拟类(接口)来减少当前项目中不同类的实现之间的依赖关系。对于我来说,即使在层次结构中,也有扩展其他纯虚拟类的纯虚拟和非纯虚拟类,这并不少见。以下是这种情况的一个例子:
class Engine
{ /* Declares pure virtual methods only */ }
class RunnableEngine : public virtual Engine
{ /* Defines some of the methods declared in Engine */ }
class RenderingEngine : public virtual Engine
{
我理解虚拟基类机制的存在是为了防止“钻石”问题。但我很好奇,如果重新设计类层次结构不能更好地处理这种情况。以以下案例为例:
class A { public: void Foo() {} };
class B : public virtual A {};
class C : public virtual A {};
class D : public B, public C {};
我现在看到的机制存在的问题是,您需要能够预测某个人将从B和C继承过来吗?所以,这并不意味着我们最好用虚拟标记来标记每一个继承?
当我试图用一种常见的方式--使用虚拟继承--来“解决”通常的钻石问题时,出现了一个奇怪的问题:
A
/ \* both virtual
B C
\ /
D
然而,我的基类A没有默认构造函数,所以我从D手动调用它。然而,当我试图将一个类E添加到这个菱形中作为C继承时
A
/ \* both virtual
B C
\ / \
D E
仍然需要在E构造函数中手动调用A的构造函数,即C不需要从E创建A,即使没有多重继承也没有钻石A-C-E。
class A
{public:
A (int _N): N(
我知道钻石问题,但问题是-当我谷歌“虚拟继承”,结果提到只钻石问题。我想知道它一般是如何工作的,它与正常的继承有什么不同。
我知道当一个类(通常)从另一个类继承时,它只包含它的所有成员(字段和方法,不包括访问级别)。其中一些可能被新成员覆盖或隐藏,但它们仍然存在。继承还定义了层次结构中类之间的某些关系,从而影响到转换和多态性。
虚拟继承有何不同?例如:
class A
{
public:
int a;
int b;
void fun(int x)
{}
void gun(int x)
{}
};
class B : public A
{
为了解决钻石问题,我们采用虚拟继承。
class A {}
class B : virtual Public A {}
class C : virtual Public A {}
class D : public B, Public C {}
为什么它不是这样定义的:
class A {}
class B : public A {}
class C : public A {}
class D : virtual public B, virtual public C {}
在C++中有解决菱形问题的现有解决方案而不是第二个解决方案背后的技术原因是什么?改变基类的继承来解决派生类中的一些问题不是很
考虑以下程序:
#include <iostream>
#include <string>
class B
{
public:
int n;
B() : n(0) {}
B(int m) : n(m) {}
};
class D1 : virtual public B
{
public:
int a;
D1() : a(0) {}
D1(int m) : a(m) {}
};
class D2 : public D1
{
public:
int d;
D2() : d(0) {}
C++:我有一个具有纯虚函数f()的基类A,然后两个类B和C实际上继承了A,而类D继承了B和C(典型的钻石结构):
A f() = 0
v/ \v
B C
\ /
D
在以下情况下,f() =0需要在何处和何时实现?
B和C都有纯虚拟函数(->做抽象类必须实现继承的纯虚拟?)
其中只有一个(B )有一个纯虚函数(->是否仍然必须实现f()?)
B和C都没有自己的纯虚拟化(->可以跳过B和C中的实现,并将其“传递”给D?)
在上述三种情况中的哪一种情况下,D需要实现f()?在何种情况下,D可以选择实现f()?在哪种情况下,如果有的话,D不
下面的代码是钻石问题。虚拟继承解决了这种模糊性。
#include<iostream>
using namespace std;
class A {
public: void something(){cout<<"A"<<endl;}
};
class B: virtual public A
{
public: void something() {cout<<"B"<<endl;}
};
class C: virt
想象一下标准的钻石遗产。A类定义纯虚拟函数fx,B类定义fx实现,C类和D类对fx不做任何操作。当尝试在类D的实例上调用fx时,尽管只有一个fx的实现,但您将得到“模糊函数调用”错误。这可以通过B和C以虚拟方式从A继承来解决。这是解决问题的正确办法吗?虚拟继承如何处理虚拟函数表的合并?
A
-->C-^
我理解并阅读了足够多的关于钻石问题的文章,它是通过虚拟继承解决的。我的问题是
“将虚拟放置在基类旁边,实际上意味着什么?”
class A { public: void Foo() {} };
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {};
我想知道我的理解是否正确。在声明中
class D : public B, public C {}
编译器将检查第一个基类B,并注意到它实际上是从class A继承的。编译器将检查A类的实例是否存在,如果
我已经检查过其他问题,令人惊讶的是,这个问题似乎没有被问到。通过扩展方法,接口提供了有限但真正的实现多重继承。这带来了钻石问题,就像基于类的多重继承一样。为什么这比基于类的多重继承更好或者更可接受,而许多人似乎觉得这很可怕?实际上,实现多重继承的方式似乎要糟糕得多,因为扩展方法不能进入接口本身,甚至不能进入实现接口的类,但最终可能分散在多个静态实用程序类上。
Eric Lippert在他的博客(2009年10月5日上午9:29 )中似乎对扩展属性的想法持开放态度,甚至提到了扩展事件、扩展操作符、扩展构造函数(也称为“工厂模式”)的可能性。因此,通过接口实现可以进一步扩展。
编辑:来说明一个类是
在以下代码中:
#include <iostream>
class a {
char a;
};
class b : virtual public a {
char b;
};
class c : virtual public a {
char c;
};
class d : public b, public c {
char d;
};
int main() {
std::cout << "sizeof a: " << sizeof(a) << std::endl;
st
我没有解释C++中的钻石问题。众所周知,这个问题可以通过虚拟继承来解决。我的查询是,创建的外孙对象的大小比没有虚拟继承的对象要重得多。让我们考虑下面的示例,以便更好地理解
#include<iostream>
using namespace std;
class base
{
};
class child1 : virtual public base
{
};
class child2 : virtual public base
{
};
class gchild : public child1, public child2
{
};
int main()
{
在下面的代码中,我得到以下警告和错误:
test.cpp:15: warning: direct base 'B' inaccessible in 'D' due to ambiguity
test.cpp:15: error: no unique final overrider for 'virtual void A::f()' in 'D'
但是如果我从A(即struct B : public A)中删除B的虚拟继承,我只得到警告,没有错误。
struct A
{
virtual void f() = 0;
};
str
#include <iostream>
using namespace std;
class A { public: void eat(){ cout<<"A";} };
class B: public A { public: void eat(){ cout<<"B";} };
class C: public A { public: void eat(){ cout<<"C";} };
class D: public B,C { public: void eat(
以下代码崩溃(访问冲突错误)是因为我使用了虚拟继承。
AFAIK虚拟继承通过强制使用类的单个实例来解决钻石问题。在这种情况下,Derived类只继承了IObject的一个实例,所以应该没有问题,但它会崩溃。
class IObject
{
public:
virtual int getType()=0;
};
class Base : public IObject
{
protected:
int val;
public:
Base() { val = 1; }
virtual int getType();
};
int Base::getType() { re
多重继承有问题。我解决了钻石问题:
class A
{
int m;
int n;
public:
A(int x, int y)
{
m = x; n = y
}
fA() {}
};
class B : virtual public A // B has fA(),fB()
{
public:
B(int k) : A(1, k) {}
fB() {}
};
class C : virtual public A // C has fA(),fC()
{
public:
C(int k) : C(2,
考虑:
#include <iostream>
using namespace std;
class A {// base class
private:
int data;
public:
A(int data = 0)
{
this->data = data;
}
void show()
{
cout << data << endl;
return;
}
};
class B : virtual public A {
public:
我试图解决一个钻石继承问题,类P从N继承,O继承类N,O继承从M继承。
M
/ \
N O
\ /
P
报头
class M {
public:
M();
M(int aVal);
int a;
};
class N : virtual public M {
public:
N();
N(int aVal, int bVal);
void foo();
int b;
};
class O : virtual public M {
public:
O();
O(int aVa
因此,我们有经典的钻石问题和int's解:
class A
{
public:
A()
{
std::cout << "A c'tor" << std::endl;
}
void f()
{
std::cout << "A::f()" << std::endl;
}
};
class B :virtual public A{};
class C :virtual public A{};
class D : publ
我目前正在进行一个C++设计,在这里我有这样的继承结构:
A
/ \
B C
类A执行类B和C共同的计算,类B和C是初始化A的两种不同方法。
我想添加某种混合初始化,即使用来自B和C的方法的类C。
但是,我需要使用钻石继承来访问B::init()和C::init()来设置D的属性。
我知道我可以使用虚拟继承避免钻石问题,但是当我手动复制方法时,我会得到运行时错误。此外,在尝试实例化类B和C时,我遇到了问题,一位同事建议我不要在设计中使用钻石继承。
因此,我想找到某种“干净”的解决办法,这是我无法做到的。
我可以将所有初始化例程都放在类A中,但目前它们很好地分开,我希望避免有一个大
我理解在钻石继承树中虚拟继承的效应,但不理解非钻石继承树中的副作用(如果有的话)。
如果你刚刚
class A;
class B: public virtual A;
这两个类的行为或内存布局(如果有的话)有什么不同,即构造函数调用的顺序等等。
假设class A有数据成员。
请为您的回答提供正式文件
考虑下面的代码片段:
class A
{
};
class B:public virtual A
{
};
class C:public virtual A
{
};
class D:public B,public C
{
};
int main()
{
cout<<sizeof(A)<<" "<<sizeof(B)<<" "<<sizeof(C)<<" "<<sizeof(D));
return 0;
}
我得到的是:
1 4 4 8
由
我在做一个我还没有开始的大项目。我的任务是在已经存在的基础上添加一些额外的功能。我的情况是,我必须使用虚拟继承,因为我有一个钻石模型。有关情况的说明如下:
Base class
/ \
/ \
My new class A class that was there before (OldClass)
\ /
\ /
\ /
\ /
My other new class
为此,中间中的两个类都是通过pub
我希望在钻石继承中更喜欢一个类中的变量。
这是代码:
class DiamondBase { protected: int x; };
class DiamondSonA: public DiamondBase {};
class DiamondSonB: public DiamondBase {};
class DiamondGS: public DiamondSonA, public DiamondSonB {
void func() { x = x; }
};
我犯了个错误
错误:对“x”的引用不明确
我可以像这样用x / C::x用func()写地址。
但是我想从B类中
这是我关于堆栈溢出的第一篇文章,所以请轻点:)
我有标准钻石问题,但我设法解决了。
class Control
{
public:
bool Focused;
};
class Caption : public virtual Control
{
public:
string Text;
};
class Frame : public virtual Control { };
class Textbox : public Caption, public Frame, public TextEditor { };
不幸的是,另一个继承问题出
好的,我知道当你完全控制所有的类时,如何解决死亡钻石继承的问题,但是如果你只控制最后一个类来继承这两个类怎么办,所以我有这个:
class A {};
class B : public A {};
class C : public A {};
class D : public B, public C {};
我没有办法编辑B和C,只有D,有没有简单的方法可以做到这一点?
关于钻石问题的维基百科:
"...菱形问题是当两个类B和C从A继承,而类D从B和C继承时出现的歧义。如果D中的方法调用在A中定义的方法(并且没有覆盖该方法),并且B和C以不同的方式覆盖了该方法,那么它从哪个类继承: B,还是C?“
所以钻石看起来是这样的:
A
/ \
B C
\ /
D
我的问题是,如果没有这样的类A,但B和C又声明了相同的方法,比如foo(),会发生什么?这不是同样的问题吗?为什么它被称为钻石问题呢?
示例:
class B {
public void foo() {...}
}
class C {
public void foo(