我可以看到人们一直在询问是否应该在下一版本的C#或Java中包含多重继承.有幸拥有这种能力的C++人说,这就像给某人一条绳子最终自我吊死.
多重继承有什么问题?有没有具体的样品?
我在C ++中使用多重继承,并通过显式调用基本方法来扩展基本方法。假定以下层次结构:
Creature
/ \
Swimmer Flier
\ /
Duck
Run Code Online (Sandbox Code Playgroud)
对应于
Creature
/ \
Swimmer Flier
\ /
Duck
Run Code Online (Sandbox Code Playgroud)
现在,这带来了一个问题-调用duck的print方法将调用其各自的基本方法,所有这些方法都依次调用该Creature::print()方法,因此最终被两次调用-
I'm a creature
I can fly
I'm a creature
I can swim
I'm a duck
Run Code Online (Sandbox Code Playgroud)
我想找到一种方法来确保基本方法仅被调用一次。与虚拟继承的工作方式类似(在第一次调用时调用基本构造函数,然后仅在来自其他派生类的后续调用中为其分配一个指针)。
是否有一些内置方法可以做到这一点,还是我们需要依靠自己实现?
如果是这样,您将如何处理?
这个问题并非特定于打印。我想知道是否有一种机制可以扩展基本方法和功能,同时保持调用顺序并避免出现钻石问题。
我现在知道,最突出的解决方案是添加辅助方法,但是我只是想知道是否存在“更清洁”的方法。
编辑3:请务必在回答之前清楚地了解我的要求(有EDIT2和很多评论).有(或有)许多答案清楚地表明对问题的误解(我知道这也是我的错,对不起)
嗨,我class B: public virtual A {...}在C++中查看了关于虚拟继承()的问题,但没有找到我的问题的答案.
我知道虚拟继承存在一些问题,但我想知道的是虚拟继承被认为是一种好的设计.
我看到人们提到类似IUnknownor的接口ISerializable,而且该iostream设计也基于虚拟继承.那些是很好地利用虚拟继承的好例子,是因为没有更好的选择,或者因为在这种情况下虚拟继承是正确的设计?谢谢.
编辑:澄清,我问的是现实生活中的例子,请不要抽象.我知道虚拟继承是什么以及哪种继承模式需要它,我想知道的是何时它是做事的好方法而不仅仅是复杂继承的结果.
EDIT2:换句话说,我想知道钻石层次结构(这是虚拟继承的原因)何时是一个好的设计
当我创建一个std :: vector对象时,并不总是调用这些对象的构造函数.
#include <iostream>
#include <vector>
using namespace std;
struct C {
int id;
static int n;
C() { id = n++; } // not called
// C() { id = 3; } // ok, called
};
int C::n = 0;
int main()
{
vector<C> vc;
vc.resize(10);
cout << "C::n = " << C::n << endl;
for(int i = 0; i < vc.size(); ++i)
cout << i << ": " << vc[i].id << endl;
}
Run Code Online (Sandbox Code Playgroud)
这是我得到的输出:
C::n = 1 …Run Code Online (Sandbox Code Playgroud) 我理解在使用多重继承时需要虚拟继承 - 它解决了Dreaded Diamond问题.
但是,如果我不使用多重继承怎么办? 是否需要虚拟继承?
我似乎记得听说它对异常很重要(抛出派生类,通过基类引用捕获).但虚拟析构函数不应该足够吗?
我已经尝试过搜索我曾经看过的参考页面,但我似乎无法找到它.
为什么大多数编程语言都不支持多继承?
我真的可以使用这个功能来开发不同的应用程序布局吗?
我有两个PHP特征,每个特征都继承自相同的第三特征:
trait C {
public function smallTalk() {
echo 'c';
}
}
trait A {
use C;
public function ac() {
echo 'a'.smallTalk();
}
}
trait B {
use C;
public function bc() {
echo 'b'.smallTalk();
}
}
Run Code Online (Sandbox Code Playgroud)
我想在课堂上使用它们:
class D {
use A, B;
public function acbc() {
echo ac().bc();
}
}
Run Code Online (Sandbox Code Playgroud)
但我一直在收到错误
致命错误:特征方法smallTalk尚未应用,因为与D上的其他特征方法存在冲突
我知道use_once这不是一件事,但我正在寻找相同的功能require_once或include_once提供,但对于特征.这个例子很简单.我的真实C有很多方法,并且被超过2个特征所继承,所以我真的不想在insteadof每次使用超过1个这些特征时重复长字符串.
我对C++的更高级功能有些新意.昨天,我发布了以下问题,我了解了虚拟继承和可怕的死亡钻石.
我还通过其他链接了解到,多重继承通常是代码设计错误的标志,并且通常可以在不使用MI的情况下更好地实现相同的结果.问题是......我不知道对于以下问题,什么是更好的单继承方法.
我想为两种类型的数字点定义一个接口.输入数字点和输出数字点.接口要纤薄,只需要访问信息所需的内容.当然,绝大多数属性对于两种类型的数字点都是通用的.所以对我来说,这是一个明显的继承案例,而不是构成.
我的界面定义看起来像这样:
// Interface Definitions
class IDigitalPoint
{
public:
virtual void CommonDigitalMethod1() = 0;
};
class IDigitalInputPoint : virtual IDigitalPoint
{
public:
virtual void DigitialInputMethod1() = 0;
};
class IDigitalOutputPoint : virtual IDigitalPoint
{
public:
virtual void DigitialOutputMethod1() = 0;
};
Run Code Online (Sandbox Code Playgroud)
我的实现看起来像这样:
// Implementation of IDigitalPoint
class DigitalPoint : virtual public IDigitalPoint
{
public:
void CommonDigitalMethod1();
void ExtraCommonDigitalMethod2();
}
// Implementation of IDigitalInputPoint
class DigitalInputPoint : public DigitalPoint, public IDigitalInputPoint
{
public:
void DigitialInputMethod1();
void ExtraDigitialInputMethod2();
} …Run Code Online (Sandbox Code Playgroud) 我试图弄清楚它是否可能在ASP.Net MVC的视图中有多重继承.现在我正试图在一个视图中从我的模型中打印出来自两个不同表的条目列表.我的视图顶部有以下行:
Inherits="System.Web.Mvc.ViewPage<List<GEApproval.Models.CoursePrefix>>"
Run Code Online (Sandbox Code Playgroud)
但我也希望将课程包括如下:
Inherits="System.Web.Mvc.ViewPage<List<GEApproval.Models.Course>>"
Run Code Online (Sandbox Code Playgroud)
我不确定如何实现这一点,任何帮助或建议都表示赞赏.
更新:
谢谢大家的帮助,我继续创建了一个复合类,如下所示:
namespace GEApproval.Models
{
public class Listings: GEApproval.Models.CoursePrefix, GEApproval.Models.ICourse
{
public List<CoursePrefix> CoursePrefixObjList { get; set; }
public List<Course> CourseObjList { get; set; }
private GEApprovalDataModel _db;
//Constructor
public Listings()
{
_db = new GEApprovalDataModel();
}
//Generate a list of all courses associated with the prefix and place in ViewData model
public void listCourses(ViewDataDictionary viewData, int prefixID)
{
var test = _db.CoursePrefix.Include("Course").First(cp => cp.id == 1);
//Show total courses for this prefix
viewData.Model …Run Code Online (Sandbox Code Playgroud) 看看这段代码
#include<iostream>
using namespace std;
//Shape is an Interface Class. No data and everything pure virtual
class Shape {
public:
virtual void Area(int length, int breadth) = 0;
virtual void Perimeter(int length, int breadth) = 0;
//Note, no data
};
//Derived class - Inherits Shape as Public
class Rectangle : public Shape {
public:
void Area(int length, int breadth);
void Perimeter(int length, int breadth);
private:
int someData;
};
//Derived class - Inherits Shape as Public
class Triangle : public Shape …Run Code Online (Sandbox Code Playgroud) 拥有多重继承的优点和缺点是什么?
而为什么我们不具备在C#多重继承?
UPDATE 好的,所以它当前被避免了,因为碰撞解决了哪个父方法被调用等问题.当然这是程序员要解决的问题.或者也许这可以像SQL一样解决,因为存在冲突需要更多信息,即ID可能需要成为Sales.ID来解决查询中的冲突.
给出以下代码:
namespace Example1 {
class A {
public:
A() {}
virtual ~A() {}
private:
float data_A;
};
class B {
public:
B() {}
virtual ~B() {}
protected:
float data_B;
};
class Derived : public A, public B {
public:
Derived() {}
virtual ~Derived() {}
protected:
float data_Derived;
};
}
int main (void)
{
using namespace Example1;
B* pb = new Derived;
delete pb;
}
Run Code Online (Sandbox Code Playgroud)
pb现在应该指向对象的B一部分Derived.但派生对象也派生自A,意味着它具有A子对象..并且该A子对象应该是"第一",因为Derived该类首先继承自A. …
我的问题如下.我想创建一个新的小部件,它是一个QTableWidget+ a QMenuBar(具有特定的配置QTableWidget).目前,我已经创建了一个MyWidget,它派生自QWidget并包含一个QTableWidget+ a QMenuBar.但有可能通过推导做同样的事情MyWidget,从QTableWidget和QMenuBar?如果有可能构造函数是什么样的?
c++ ×8
inheritance ×4
oop ×2
asp.net ×1
asp.net-mvc ×1
c# ×1
constructor ×1
html ×1
php ×1
qt ×1
static ×1
stdvector ×1
stl ×1