我正在阅读关于继承的内容,我有一个我几个小时都无法解决的重大问题:
鉴于一个类Bar是一个具有virtual函数的类,
class Bar
{
virtual void Cook();
};
Run Code Online (Sandbox Code Playgroud)
有什么不同:
class Foo : public Bar
{
virtual void Cook();
};
Run Code Online (Sandbox Code Playgroud)
和
class Foo : public virtual Bar
{
virtual void Cook();
};
Run Code Online (Sandbox Code Playgroud)
?谷歌搜索和阅读的时间提供了大量有关其用途的信息,但实际上没有人告诉我两者之间有什么区别,只是让我更加困惑.
假设有这个界面:
class A{
public:
virtual foo()=0;
};
Run Code Online (Sandbox Code Playgroud)
以及B实现此接口的类:
class B:public A{
public:
virtual foo(){} //Foo implemented by B
}
Run Code Online (Sandbox Code Playgroud)
最后,一个C具有类A和B基类的类:
Class C : public A, public B {
};
Run Code Online (Sandbox Code Playgroud)
我的问题是,有一种方法可以告诉编译器,实现foo是来自类的实现B而不进行显式调用B::foo()?
struct A {
virtual void foo() { std::cout << "a";};
};
struct B:public virtual A {
void foo() { std::cout << "b";}
};
struct C:public virtual A {
void foo() { std::cout << "c";}
};
struct D:public B, public C {
};
int main() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
因此,在编译时会出现以下错误:
\main.cpp:16:8: error: no unique final overrider for 'virtual void A::foo()' in 'D'
struct D:public B, public C {
Run Code Online (Sandbox Code Playgroud)
如果我们将B和C结构的继承设为非虚拟的,则代码将正确编译而没有任何错误(但是,如果我们调用dd.foo(),则错误当然会发生)。那有什么区别呢?为什么当我们虚拟继承我们的类时出现错误,而如果直接继承则没有错误呢?
我想了解为什么 C++ 标准要求虚拟基非默认构造函数不能由中间非最派生类调用,如这段代码中所示,当使用 '-D_WITH_BUG_' 编译时:
/* A virtual base's non-default constructor is NOT called UNLESS
* the MOST DERIVED class explicitly invokes it
*/
#include <type_traits>
#include <string>
#include <iostream>
class A
{
public:
int _a;
A(): _a(1)
{
std::cerr << "A() - me: " << ((void*)this) << std::endl;
}
A(int a): _a(a)
{
std::cerr << "A(a) - me:" << ((void*)this) << std::endl;
}
virtual ~A()
{
std::cerr << "~A" << ((void*)this) << std::endl;
}
};
class B: public virtual …Run Code Online (Sandbox Code Playgroud) 我目前正在尝试在我的项目中实现多种继承类。因此,我正在使用成员初始化器列表,并将“变量”一直引用到基类。我真的不确定,为什么会出现编译器错误。
我已经尝试将引用“ int&id”更改为指针“ int * id”。上面的示例只是指出我的问题的一个最小示例:
class Base
{
public:
int& m_id;
Base(int &id)
: m_id(id)
{
}
};
class Derived1: virtual public Base
{
public:
Derived1(int &id) : Base(id)
{
};
};
class Derived2: public Derived1
{
public:
Derived2(int &id) : Derived1(id)
{
};
};
int main()
{
int i = 13;
Derived2 Test(i);
}
Run Code Online (Sandbox Code Playgroud)
尝试编译时出现以下错误消息:
“错误:没有匹配的函数可以调用'Base :: Base()'”
任何想法,我在做什么错?
谢谢你的帮助。
根据我的阅读,当你有一个包含数据的抽象基类时,会使用虚基类,所以不会复制类,但是,如果不使用虚拟类,复制类有什么问题?
应该避免使用保存数据的抽象基类吗?
举个例子:
class Storable {
public:
Storable(const string& s);
virtual void read() = 0;
virtual void write() = 0;
virtual ~Storable();
protected:
string file_name; // store in file named s
Storable(const Storable&) = delete;
Storable& operator=(const Storable&) = delete;
};
class Transmitter : public virtual Storable {
public:
void write() override;
// ...
};
class Receiver : public virtual Storable {
public:
void write() override;
// ...
};
class Radio : public Transmitter, public Receiver {
public:
void write() …Run Code Online (Sandbox Code Playgroud) class A: public B, public C { };
Run Code Online (Sandbox Code Playgroud)
在这种情况下,执行顺序是:
B(); // base(first)
C(); // base(second)
A(); // derived
Run Code Online (Sandbox Code Playgroud)
class A: public B, virtual public C { };
Run Code Online (Sandbox Code Playgroud)
但是在这种情况下,当我在继承时用c类写虚拟时,顺序为
// execution becomes:
C(); // virtual base
B(); // ordinary base
A(); // derived
Run Code Online (Sandbox Code Playgroud)
我已经读过某个地方,调用构造函数的顺序依赖于声明的顺序,同时继承多个类但是如何在用类编写虚拟时改变执行的顺序.我无法理解为什么我得到这样的结果.
在尝试重用不同类的代码时,我偶然发现了一个问题.我在这里发帖,希望你们中的一些人能够帮助我.
我有一组派生自同一个类(A)的类(B,C),这些类强制执行某些方法(foo,run).B类实现了这些方法,B和C都提供了其他方法:
#include<iostream>
template<class I, class O>
class A {
public:
A() {}
virtual ~A() {}
virtual void foo() const = 0; // force implementation of this function
virtual void run() const = 0; // force implementation of this function
};
template<class I, class O>
class B : public A<I,O> {
public:
B() {}
virtual ~B() {}
virtual void foo() const { // implementation for the Base class
std::cout << "B's implementation of foo" << std::endl;
}
virtual void run() …Run Code Online (Sandbox Code Playgroud) 正如"The C++ Programming Language 3.Edition - Bjarne Stroustrup"中所写.我们可以使用范围解决方案来防止歧义错误.下面的基本程序,当我在类混合使用3层范围时发生错误.但是,当我使用2层没有问题.怎么了?还是像设计问题?错误是;
deneme.cpp: In constructor ‘mix::mix(std::__cxx11::string, int)’:
deneme.cpp:45:22: error: ‘plane’ is an ambiguous base of ‘mix’
pervaneli::plane::engine=b;
Run Code Online (Sandbox Code Playgroud)
我不想制作钻石模型.我很满意两个基础(平面)课程.我只是想了解为什么当我使用3层范围时它会出错.谢谢.
注意:版本是g ++(Ubuntu 5.4.0-6ubuntu1~16.04.4)5.4.0 20160609
#include<iostream>
#include<string>
using namespace std;
class plane{
protected:
int speed;
string name;
public:
int engine;
void its_name(){
cout<<name<<endl;
}
plane(int a=10000){
engine=a;
}
};
class pervaneli:public plane{
public:
pervaneli(string a="-"){
name=a;
}
void belirle(int x){
speed=x;
}
};
class jet:public plane{
public:
jet(string a="-"){
name=a;
}
void belirle(int x){
speed=x;
}
}; …Run Code Online (Sandbox Code Playgroud) 我有3个类A,B并C声明为
class A {
int varA;
};
class B {
int varB;
};
class C : public A, public B {
void setVar(int var) {
varA = var;
varB = var; // <- duplicate
}
};
Run Code Online (Sandbox Code Playgroud)
现在类C将有2个变量varA和varB.在我的例子中,两个变量具有相同的含义(例如,物理对象的位置),因此总是需要相同,因为成员函数只会对自己的变量进行计算.
我想增加一个父类A和B,但后来同样的问题仍然存在:
class Parent {
public:
int var;
};
class A : public Parent {};
class B : public Parent {};
class C : public A, public B …Run Code Online (Sandbox Code Playgroud) c++ ×10
inheritance ×6
c++11 ×2
abstract ×1
c++17 ×1
constructor ×1
oop ×1
pure-virtual ×1
virtual ×1