标签: virtual-functions

多重继承+虚函数混乱

我有一个像这样的钻石多重继承场景:

    A
  /   \
 B     C
  \   /
    D
Run Code Online (Sandbox Code Playgroud)

公共父A定义了虚函数fn().
B和C都可以定义fn()吗?
如果是,那么下一个问题是 - D可以访问B和C的fn()而不消除歧义吗?我假设有一些语法...
而D是否有可能在不知道谁是B和C的情况下做到这一点?B和C可以替换为其他类,我希望D中的代码是通用的.

我想要做的是让D以某种方式枚举它在其祖先中具有的fn()的所有实例.这是否可能在某些其他方面表示虚函数?

c++ virtual-functions multiple-inheritance diamond-problem

17
推荐指数
3
解决办法
3万
查看次数

C++将未知类型传递给虚函数

我正在用C++编写,我想将一个未知类型(仅在运行时知道)传递给纯虚函数:

virtual void DoSomething(??? data);
Run Code Online (Sandbox Code Playgroud)

where DoSomething是派生类中纯虚函数的实现.

我打算使用模板,但因为它结果是虚函数和模板不能一起工作:C++类成员函数模板可以是虚拟的吗?

我想避免为我传递给函数的所有类使用基类(类似于C#中的对象).

提前致谢

c++ templates virtual-functions

17
推荐指数
1
解决办法
2898
查看次数

成员函数模板不能声明为虚拟 - 来自Addison Wesley:C++模板

来自Addison Wesley:C++模板

成员函数模板不能声明为虚拟.强加此约束是因为虚函数调用机制的通常实现使用固定大小的表,每个虚函数有一个条目.但是,在翻译整个程序之前,成员函数模板的实例化数量不固定.

以上引用是否意味着模板具有静态绑定,虚拟功能具有动态绑定,这就是不能有虚拟功能模板的原因?请查看是否可以用外行的语言进行解释.

c++ templates virtual-functions

16
推荐指数
2
解决办法
8117
查看次数

C++指向虚函数的指针

如果你有这样的结构

struct A {
    void func();
};
Run Code Online (Sandbox Code Playgroud)

和像这样的参考

A& a;
Run Code Online (Sandbox Code Playgroud)

你可以func像这样得到一个指向它的方法的指针:

someMethod(&A::func);
Run Code Online (Sandbox Code Playgroud)

现在,如果该方法是虚拟的并且您不知道它在运行时是什么,该怎么办?为什么你不能得到像这样的指针?

someMethod(&a.func);
Run Code Online (Sandbox Code Playgroud)

是否有可能获得指向该方法的指针?

c++ virtual-functions member-function-pointers function-pointers

16
推荐指数
2
解决办法
2万
查看次数

解释为什么构造函数不能基于研究虚拟化:纠正错误(如果有的话)

我做了一些研究,找出为什么构造函数不能虚拟.我在这里巩固了我的理解.

我将首先解释什么是虚函数,然后根据第一个解释解释为什么构造函数不能是虚函数.

什么是virtual function

虚函数是基类中的函数或方法,可以通过具有相同签名的函数在派生类中重新定义或覆盖.换句话说,虚函数允许在派生类中具有基类方法的自定义实现.它需要使用virtual关键字声明.在虚函数调用时,决定在运行时选择函数定义的哪个版本(在基类或派生类中),具体取决于调用对象的类型(动态绑定).

当函数声明为virtual时,它告诉编译器应该仅在运行时确定调用虚函数的对象的类型.然后根据对象的类型,函数调用应该绑定到函数定义,并且应该调用适当的函数.

为什么一个constructor不能虚拟?

当函数声明为virtual时,它告诉编译器应该仅在运行时确定调用该函数的对象的类型,然后根据对象的类型调用该函数的相应版本.

如果要将构造函数声明为virtual,它将告诉编译器应该在运行时确定将调用构造函数的对象类型.但是对于构造对象,应该在编译时而不是在运行时知道对象的确切类型.这就是构造函数不能虚拟的原因.

我希望SO成员纠正两个答案中的错误,如果有的话.我认为这对我和其他人有帮助,如果你可以通过重写它作为你的答案来纠正答案,而不是仅仅指出错误.

c++ constructor virtual-functions dynamic-binding

16
推荐指数
0
解决办法
2万
查看次数

在方法覆盖中更改params修饰符

我知道params修饰符(将数组类型的一个参数转换为所谓的"参数数组")特别不是方法签名的一部分.现在考虑这个例子:

class Giraffid
{
    public virtual void Eat(int[] leaves)
    {
        Console.WriteLine("G");
    }
}
class Okapi : Giraffid
{
    public override void Eat(params int[] leaves)
    {
        Console.WriteLine("O");
    }
}
Run Code Online (Sandbox Code Playgroud)

编译时没有任何警告.然后说:

var okapi = new Okapi();
okapi.Eat(2, 4, 6);  // will not compile! 
Run Code Online (Sandbox Code Playgroud)

给出一个错误(No overload for method 'Eat' takes 3 arguments).

现在,我知道编译器会将params修改器转换为System.ParamArrayAttribute相关参数的应用程序.通常,将一个属性集合应用于虚方法的参数,然后在具有不同属性集的派生类中的重写方法中装饰"对应"参数是没有问题的.

然而,编译器选择params静默忽略我的关键字.相反,如果一个使它反过来,并且应用于params基类中的参数Giraffid,然后省略覆盖中的关键字Okapi,编译器选择用它来装饰两个方法System.ParamArrayAttribute.当然,我用IL DASM验证了这些东西.

我的问题:

这是记录在案的行为?我已经彻底搜索了C#语言规范,但没有发现任何提及.

我可以说至少Visual Studio开发环境对此感到困惑.当键入2, 4, 6在上述方法的调用,所述 …

c# overriding virtual-functions params-keyword params

16
推荐指数
2
解决办法
1121
查看次数

如何使用重载和重写方法解释此行为?

任何人都可以这么好,并解释为什么这个代码显示Derived.DoWork(double).我可以为这种行为提出一些解释,但我希望有人为我澄清这一点.

using System;

public class Base
{
    public virtual void DoWork(int param) {
        Console.WriteLine("Base.DoWork");
    }
}

public class Derived : Base
{
    public override void DoWork(int param) {
        Console.WriteLine("Derived.DoWork(int)");
    }

    public void DoWork(double param) {
        Console.WriteLine("Derived.DoWork(double)");
    }

    public static void Main() {
        int val = 5;
        Derived d = new Derived();
        d.DoWork(val);
    }
}
Run Code Online (Sandbox Code Playgroud)

c# virtual-functions overloading

16
推荐指数
1
解决办法
231
查看次数

Arduino C++代码:您可以使用虚函数和异常吗?

编写固件:汇编或高级别的问题开始对此评论进行跟进:

在为Arduino平台编译C++代码时,您可以使用虚函数,异常等吗?或者你想(必须)使用C++的一个子集(如评论所述)?

在为Arduino平台编程时还有其他注意事项吗?

c++ virtual-functions arduino firmware

15
推荐指数
2
解决办法
1万
查看次数

为什么这个虚拟析构函数会触发一个未解析的外部?

考虑以下:

Xh:

class X
{
    X();
    virtual ~X();
};
Run Code Online (Sandbox Code Playgroud)

X.cpp:

#include "X.h"

X::X()
{}
Run Code Online (Sandbox Code Playgroud)

尝试构建这个(我使用的是.dll目标,以避免在丢失的main上出现错误,我正在使用Visual Studio 2010):

错误1错误LNK2001:未解析的外部符号"private:virtual __thiscall X :: ~X(void)"(?? 1X @@ EAE @ XZ)

然而,小的修改导致成功构建:

XH:

class X
{
    inline X(); // Now inlined, and everything builds
    virtual ~X();
};
Run Code Online (Sandbox Code Playgroud)

要么

XH:

class X
{
    X();
    ~X(); // No longer virtual, and everything builds
};
Run Code Online (Sandbox Code Playgroud)

当.dtor是虚拟的或者.ctor没有内联时,是什么导致链接器中未解析的外部?

编辑:

或者,或许更有趣的是,如果我将析构函数设置为非虚拟,或者如果我内联构造函数,为什么我没有得到未解析的外部?

c++ destructor virtual-functions unresolved-external

15
推荐指数
3
解决办法
1万
查看次数

在C++纯虚函数上应用"using"关键字

B类覆盖了A类的纯虚函数"print()".C类继承了B类,并且具有"使用A :: print"语句.既然C类不是抽象类呢?

class A {
    public :
        virtual void print() =0;
};

class B:public A {
    public:
        void print();
};

void B :: print() {

    cout << "\nClass B print ()";
}

class C : public B {

    public:
        using A::print;
};

void funca (A *a) {

    // a->print(1);                    
}

void funcb (B *b) {

    b->print();         
}

void funcc (C *c) {

    c->print();             
}

int main() {
    B b;
    C c;        
    funca(&c);              
    funcb(&c);              
    funcc(&c);              
    return 0;               
}
Run Code Online (Sandbox Code Playgroud)

输出:

    Class …
Run Code Online (Sandbox Code Playgroud)

c++ overriding virtual-functions using-declaration

15
推荐指数
2
解决办法
614
查看次数