C++:继承函数并重新定义它们
C++: inheriting functions and redefining them
我在接口、继承和重新定义方面遇到了一些问题。在这种情况下,我不确定C++为什么会这样,所以如果有人能解释并帮助我的话。我有以下课程:
module.h:
class mixer;
class module {
public:
module(std::string name_) : name(name_) {}
~module() {}
virtual module& bind(module &mod) = 0;
virtual module& bind(mixer &mix) { return ((module&)mix); }
std::string get_name()
{
return name;
}
std::string name;
};
in_out.h:
class in_out : public module {
public:
in_out(std::string name_) : module(name_) {}
~in_out() {}
virtual module& bind(module &mod)
{
std::cout << "bind in_out in " << mod.name << std::endl;
return mod;
}
};
prod.h:
class prod : public in_out {
public:
prod(std::string name_)
: in_out(name_)
{}
~prod() {}
virtual module& bind(mixer &mix)
{
std::cout << "bind mixer in " << get_name() << std::endl;
return mix;
}
};
混合器.h:
class mixer : public in_out {
public:
mixer(std::string name_)
: in_out(name_)
{}
~mixer() {}
};
所以,如果在我的主文件中,我有这个:
int main(int argc, char *argv[])
{
prod prod1("prod1");
prod prod2("prod2");
mixer mixer1("mixer1");
mixer mixer2("mixer2");
prod1.bind(prod2);
return 0;
}
我得到这个错误:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:12:19: error: no matching function for call to ‘prod::bind(prod&)’
main.cpp:12:19: note: candidate is:
prod.h:19:23: note: virtual pfn_module& prod::bind(mixer&)
prod.h:19:23: note: no known conversion for argument 1 from ‘prod’ to ‘mixer&’
make: *** [main] Error 1
如果我有这个:
prod1.in_out::bind(prod2);
它按预期工作。
我不明白的是,编译器不应该区分这些吗?
virtual module& bind(module &mod) = 0;
// and
virtual module& bind(mixer &mix) { return ((module&)mix); }
我想问题可能是mixer
和prod
都是module
(和in_out
)的子代。也许当函数bind
在main中被调用时,它在prod
的定义中查找它,但只找到bind(mixer)
?bind(module)
呢?在这种情况下它是私人的吗?
我想要的是,无论我称之为prod.bind(prod)
还是prod.bind(mixer)
,它都在prod
的级别上区分它们,所以我不必从那里调用.in_out
。
非常感谢:)
问题是,当您定义类prod并声明函数绑定时
virtual module& bind(mixer &mix);
在类作用域中,隐藏了与基类同名的所有其他函数。所以你打电话给
prod1.bind(prod2);
编译器在类作用域中只看到一个候选者:上面显示的函数。并且它不能将参考脉冲转换为参考混频器。
你应该写在类定义
using in_out::bind;
正如@Alex在他的评论中指出的那样,如果使用多态性,则必须使类模块的析构函数成为虚拟的。
编辑:如果因为没有pfn_inout的定义而用pfn_inoout代替in_out,则以下代码已成功编译
#include <iostream>
#include <string>
class mixer;
class module {
public:
module(std::string name_) : name(name_) {}
~module() {}
virtual module& bind(module &mod) = 0;
virtual module& bind(mixer &mix) { return ((module&)mix); }
std::string get_name()
{
return name;
}
std::string name;
};
class in_out : public module {
public:
in_out(std::string name_) : module(name_) {}
~in_out() {}
virtual module& bind(module &mod)
{
std::cout << "bind in_out in " << mod.name << std::endl;
return mod;
}
};
class mixer : public in_out {
public:
mixer(std::string name_)
: in_out(name_)
{}
~mixer() {}
};
class prod : public in_out {
public:
using in_out::bind;
prod(std::string name_)
: in_out(name_)
{}
~prod() {}
virtual module& bind(mixer &mix)
{
std::cout << "bind mixer in " << get_name() << std::endl;
return mix;
}
};
int main()
{
prod prod1("prod1");
prod prod2("prod2");
mixer mixer1("mixer1");
mixer mixer2("mixer2");
prod1.bind(prod2);
return 0;
}
在C++中,名称查找在找到名称的范围内停止。(有一些例外,与ADL有关,但它们不适用此处。)这样做的原因是为了避免更改语义的派生if函数班
通常情况下,这不应该是一个问题,因为您应该在所有派生类。以及虚拟功能和非虚拟函数不应该共享名称。在你的情况下,你在基类中可能需要类似于:
class Module
{
private:
virtual Module& doBind( Module& mod ) = 0;
public
Module& bind( Module& mod )
{
// pre-conditions
Module& results = doBind( mod );
// post-conditions and invariants
return results;
}
Module& bind( Mixer& mix )
{
// pre-conditions
Module& results = doBind( static_cast<Module&>( mod) );
// post-conditions and invariants
return results;
}
};
派生类将实现它们自己的CCD_ 13版本,但没有别的。
不过有一件事。上下文中的转换(Module&)mix
在编译器看不到CCD_ 15的完整定义的情况下,是reinterpret_cast
,几乎可以肯定不是什么你想要的。我在示例中使用了static_cast
,以与你已经做了什么,但事实上,如果编译器看不到CCD_ 18的定义。在这种特殊情况下,事实上,第二个bind
根本不需要由于CCD_ 20将隐式转换为CCD_,而不需要您进行转换。(但它相当这段代码可能只是一个非常简单的例子在你的真实代码中,你实际上在做更多的事情复杂。)
- 在类定义之后定义一个私有方法
- Android Studio:如何在build.gradle中定义自定义宏(针对不同的构建变体),并让原生C / C++
- 如何在C++中为 if 和 else 语句定义新行为
- 如何从 C++ 中的现有模板函数定义新函数
- 如何在CPropertySheet中定义新颜色
- 谁定义新操作员
- boost :: fibonacci_heap:带有比较器重新定义圆形定义错误的嵌套定义
- C 通过Typedef定义新类型
- 在 ss.clear() 之后使用 ss.str( " ") 用于新定义的字符串流
- 是标头文件中使用“新”定义的成员指针泄漏
- 使用带有Eigen库的自定义新处理程序
- 定义新的优化类型
- C# 如何定义新的指针结构
- 为模型定义新角色后程序崩溃
- C++使用类来定义新类型
- 操作员新[]定义分解
- 为什么不调用复制构造函数将临时对象复制到新定义的对象
- Qt:在按钮点击上添加自定义新选项卡
- 定义新的中缀操作符
- 错误:不能在返回类型中定义新类型