如何在没有动态转换的情况下在覆盖函数中使用派生参数
How to use derived parameter in an overriding function without dynamic casting
谁能告诉我如何实现:
- 派生方法的参数class是参数的
派生class(不是参数的基数class)?
这就是我想要的:
class Base{
public:
// Base class method has ParameterBase parameter
virtual void f(ParameterBase pb) = 0;
}
class Derived : public Base{
public:
// I want: Derived class method has ParameterDerived parameter;
void f(ParameterDerived pd){ //do something with pd; }
}
class ParameterBase{
// Base class of parameter;
}
class ParameterDerived : public ParameterBase{
// Derived class of parameter;
}
如何实现以上?
我是否必须在派生方法的参数列表中使用 ParamterBase 并在方法主体中使用 dynamic_cast 参数?
假设您希望使用 ParameterDerived 调用 Derived,但您还想在抽象基类中声明接口 类。
接口必须具有相同的参数类型,但您仍然可以在 Derived::f
中使用 dynamic_cast 强制执行正确的参数子类
#include <iostream>
#include <string>
// interface
struct ParameterBase {
virtual ~ParameterBase() {};
};
struct Base {
virtual void f(ParameterBase *pb) = 0;
virtual ~Base() {};
};
// specific
struct ParameterDerived : public ParameterBase {
std::string name;
ParameterDerived(const std::string &name) : name(name) {}
ParameterDerived& operator=(const ParameterDerived& rhs) { name = rhs.name; }
~ParameterDerived() {};
};
struct Derived : public Base {
Derived(){}
Derived& operator=(const Derived &rhs) {}
virtual ~Derived(){}
void f(ParameterBase *pb) {
ParameterDerived *pd = dynamic_cast<ParameterDerived*>(pb);
if (pd) {
std::cout << "Derived object with derived parameter " << pd->name << std::endl;
} // else {throw std::exception("wrong parameter type");}
}
};
int main() {
Derived object;
ParameterDerived param("foo");
object.f(¶m);
}
您要求的功能称为参数类型 contra-variance。不幸的是,C++ 不支持它。 C++ 仅支持 return 类型协变。 See 这里有一个很好的解释。
Perhaps inconveniently, C++ does not permit us to write the function
marked hmm... above. C++’s classical OOP system supports “covariant
return types,” but it does not support “contravariant parameter
types.”
但您可以使用 dynamic_cast<>()
运算符。但首先,您必须将参数类型更改为指针或引用,并向您的 class ParameterBase
添加至少一个虚拟成员(虚拟析构函数也算在内),以使编译器为其创建虚拟方法 table 。这是带有参考的代码。可以使用指针代替。
class ParameterBase
{
public:
// To make compiler to create virtual method table.
virtual ~ParameterBase()
{}
};
class ParameterDerived : public ParameterBase
{
};
class Base
{
public:
// Pointers or references should be used here.
virtual void f(const ParameterBase& pb) = 0;
};
class Derived : public Base
{
public:
virtual void f(const ParameterBase& pb) override
{
// And here is the casting.
const ParameterDerived& pd=dynamic_cast<const ParameterDerived&>(pb);
}
};
int main()
{
Derived d;
ParameterDerived p;
d.f(p);
}
谁能告诉我如何实现:
- 派生方法的参数class是参数的 派生class(不是参数的基数class)?
这就是我想要的:
class Base{
public:
// Base class method has ParameterBase parameter
virtual void f(ParameterBase pb) = 0;
}
class Derived : public Base{
public:
// I want: Derived class method has ParameterDerived parameter;
void f(ParameterDerived pd){ //do something with pd; }
}
class ParameterBase{
// Base class of parameter;
}
class ParameterDerived : public ParameterBase{
// Derived class of parameter;
}
如何实现以上? 我是否必须在派生方法的参数列表中使用 ParamterBase 并在方法主体中使用 dynamic_cast 参数?
假设您希望使用 ParameterDerived 调用 Derived,但您还想在抽象基类中声明接口 类。
接口必须具有相同的参数类型,但您仍然可以在 Derived::f
中使用 dynamic_cast 强制执行正确的参数子类#include <iostream>
#include <string>
// interface
struct ParameterBase {
virtual ~ParameterBase() {};
};
struct Base {
virtual void f(ParameterBase *pb) = 0;
virtual ~Base() {};
};
// specific
struct ParameterDerived : public ParameterBase {
std::string name;
ParameterDerived(const std::string &name) : name(name) {}
ParameterDerived& operator=(const ParameterDerived& rhs) { name = rhs.name; }
~ParameterDerived() {};
};
struct Derived : public Base {
Derived(){}
Derived& operator=(const Derived &rhs) {}
virtual ~Derived(){}
void f(ParameterBase *pb) {
ParameterDerived *pd = dynamic_cast<ParameterDerived*>(pb);
if (pd) {
std::cout << "Derived object with derived parameter " << pd->name << std::endl;
} // else {throw std::exception("wrong parameter type");}
}
};
int main() {
Derived object;
ParameterDerived param("foo");
object.f(¶m);
}
您要求的功能称为参数类型 contra-variance。不幸的是,C++ 不支持它。 C++ 仅支持 return 类型协变。 See 这里有一个很好的解释。
Perhaps inconveniently, C++ does not permit us to write the function marked hmm... above. C++’s classical OOP system supports “covariant return types,” but it does not support “contravariant parameter types.”
但您可以使用 dynamic_cast<>()
运算符。但首先,您必须将参数类型更改为指针或引用,并向您的 class ParameterBase
添加至少一个虚拟成员(虚拟析构函数也算在内),以使编译器为其创建虚拟方法 table 。这是带有参考的代码。可以使用指针代替。
class ParameterBase
{
public:
// To make compiler to create virtual method table.
virtual ~ParameterBase()
{}
};
class ParameterDerived : public ParameterBase
{
};
class Base
{
public:
// Pointers or references should be used here.
virtual void f(const ParameterBase& pb) = 0;
};
class Derived : public Base
{
public:
virtual void f(const ParameterBase& pb) override
{
// And here is the casting.
const ParameterDerived& pd=dynamic_cast<const ParameterDerived&>(pb);
}
};
int main()
{
Derived d;
ParameterDerived p;
d.f(p);
}