【问题标题】:How to choose the overloaded function called如何选择调用的重载函数
【发布时间】:2019-03-30 14:57:34
【问题描述】:

我是 C++ 初学者,我想更改将在此代码中调用的函数版本:

#include <iostream>

class C1 {};

class C2 : public C1 {};

void func(C1 var) {
    std::cout << "Func 1" << std::endl;
}

void func(C2 var) {
    std::cout << "Func 2" << std::endl;
}

int main() {
    C1 *teste1 = new C1;
    C1 *teste2 = new C2;

    func(*teste1);                 // Want "Func 1"
    func(*teste2);                 // Want "Func 2"

    return 0;
}

从评论中可以看出,我想要的是当我取消引用指向 C2 类的指针时调用带有 C2 参数的 func。

编辑:只是为了澄清我真正想要实现的目标,下面的代码更接近我想要的:

#include <iostream>
#include <list>

class C1 {};

class C2 : public C1 {};

void func(C1 var) {
    std::cout << "Func 1" << std::endl;
}

void func(C2 var) {
    std::cout << "Func 2" << std::endl;
}

int main() {
    std::list<C1*> teste;

    teste.push_back(new C1);
    teste.push_back(new C2);

    // Want to print:
    // Func 1
    // Func 2
    for(auto i: teste) {
        func(*i);

    }

    return 0;
}

【问题讨论】:

标签: c++ inheritance overloading


【解决方案1】:

如果您知道自己正在处理 C2 对象,则可以先转换为 C2 指针:

func(*teste1);                   // Want "Func 1"
func(*static_cast<C2*>(teste2)); // Want "Func 2"

或者,您可以通过在C1 中拥有一个虚函数来使C2 具有多态性:

class C1 {
public:
    virtual ~C1() {}
};

然后你可以做一个dynamic_cast:

func(*dynamic_cast<C2*>(teste2)); // Want "Func 2"

请注意,如果您不确定自己拥有哪种对象,dynamic_cast 将在失败时返回一个空指针,因此您可以这样做:

if(dynamic_cast<C2*>(teste2)) {
    func(*dynamic_cast<C2*>(teste2)); //If it's a C2, call the C2 overload
} else {
    func(*teste2); //If it's a C1, call the C1 overload
}

或者更好的是,如果可以避免的话,根本不要使用指针!!

【讨论】:

  • 或者从一开始就拥有正确类型的teste2
  • @SergeyA 好点,最后补充说(我觉得这是需要指针的更复杂的事情的一部分)。
  • 感谢您的回答。我想这样做的原因是因为我有一个指向类 C1 的指针列表。我希望能够在 for 中执行 func 并选择正确的函数。我想使用指针的原因是因为这样我可以添加另一个类(我已经有 3 个类,如 C2),如果将来有必要,只需更改一两段代码。如果这不可能,我将不使用指针,并为每个类创建一个列表。
  • @Gusgo99 查看我的编辑。您可以使用dynamic_cast 来判断它实际指向的内容,并根据具体情况调用不同的内容。
  • @scohe001 谢谢,这正是我要找的!
【解决方案2】:

如前所述,您可以使 func() 成为基类中的虚拟成员函数,然后覆盖它。然后调用 YourObject.func() 会返回你想要的。

虚拟函数具有查找 vtable 的开销,这在某些情况下会降低性能,但如果在编译时知道某物实际是哪种类型,则可以使用 CRTP 进行“静态多态性”。有很多关于这方面的文章,如果你走这条路,我建议你先学习模板——一定要先了解常规的虚函数。

【讨论】:

    【解决方案3】:
    #include <iostream>
    
    class C1 {
    public:
        virtual void func(){
            std::cout << "Func 1" << std::endl;
        }
    };
    
    class C2 : public C1{
    public:
        void func() override{
            std::cout << "Func 2" << std::endl;
        }
    };
    
    int main() {
        C1* teste1 = new C1;
        C1* teste2 = new C2;
    
        teste1->func();                 // Want "Func 1"
        teste2->func();                 // Want "Func 2"
    
        return 0;
    }
    

    【讨论】:

    • 谢谢你的回答,但问题是func是另一个类的成员函数,我不希望C1和C2访问这个第三类的一些成员变量。
    猜你喜欢
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    • 2018-11-04
    相关资源
    最近更新 更多