如何选择调用的重载函数
Posted
技术标签:
【中文标题】如何选择调用的重载函数【英文标题】: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;
【问题讨论】:
美丽的MCVE 和一个精彩的第一个问题。欢迎来到 ***!我希望看到更多像这样的问题! 你介意在这里找到一些有用的东西 - en.cppreference.com/w/cpp/experimental/constraints C++20。 【参考方案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访问这个第三类的一些成员变量。以上是关于如何选择调用的重载函数的主要内容,如果未能解决你的问题,请参考以下文章