Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基方法/运算符在派生(C+;+;)上调用时返回基类型?_C++_Inheritance_Typing - Fatal编程技术网

C++ 基方法/运算符在派生(C+;+;)上调用时返回基类型?

C++ 基方法/运算符在派生(C+;+;)上调用时返回基类型?,c++,inheritance,typing,C++,Inheritance,Typing,鉴于: 有没有一种方法可以使前两条语句在不重新实现派生中的每个基方法(生成调用基方法并返回派生类型的派生方法)的情况下工作,并且不需要用户进行强制转换/调用复制构造函数 编辑:所有派生对象都在基础对象集中(类继承所需),但并非所有基础对象都在派生对象集中。它们具有相同的数据成员,但派生对象具有指定给其中一个数据成员的常量值(所有派生对象的常量值相同) 有许多方法是特定于基或派生的,但大多数运算符和set/get访问器在基对象和派生对象上具有相同的定义行为。我试图做的事情是在调用派生对象上的基方法

鉴于:

有没有一种方法可以使前两条语句在不重新实现派生中的每个基方法(生成调用基方法并返回派生类型的派生方法)的情况下工作,并且不需要用户进行强制转换/调用复制构造函数

编辑:所有派生对象都在基础对象集中(类继承所需),但并非所有基础对象都在派生对象集中。它们具有相同的数据成员,但派生对象具有指定给其中一个数据成员的常量值(所有派生对象的常量值相同)

有许多方法是特定于基或派生的,但大多数运算符和set/get访问器在基对象和派生对象上具有相同的定义行为。我试图做的事情是在调用派生对象上的基方法(因为这些操作是数学上定义的)时获取派生或派生&back,而在调用基对象上的基方法时仍然获取基或基

上下文:Base是一个矩阵类,派生的是一个向量(列)类。派生(const Base&other)构造函数用于从单列(nx1)矩阵显式获取向量

所以我想:

class Base:
{
  public:
  ...
  Base operator+( const Base& other );
  Base& scale( float num );
}

class Derived : public Base:
{
  public:
  ...
  Derived( const Base& other );
  float super_math_wizardry();
}

//A user can do the following:

Base b1,b2,b3;
Derived d1,d2,d3;

b3 = b1 + b2;
d3 = d1 + d2;

b3 = b1.scale( 2.0f );
d3 = d1.scale( 3.0f ); //scale returns Base& type that is converted to Derived

float x,y;

x = (d1+d2).super_math_wizardry(); //compiler type error since d1+d2 returns Base type
y = (d1.scale(4.0f)).super_math_wizardry(); //similar compiler error

x = Derived(d1+d2).super_math_wizardry(); //works
y = Derived(d1.scale(4.0f)).super_math_wizardry(); //works

简单的回答是,不

函数的返回类型为Base。您要求编译器执行的操作与执行相同

x = (d1+d2).super_math_wizardry(); //works
y = (b1+b2).super_math_wizardry(); //fails (although possibly at run-time since a nx1 Matrix is a column vector)
根本没有办法做到这一点,因为语言无法知道上面和后面的区别

Derived d1;
Base* b = &d1;
b->super_math_wizardry(); // This is also wrong since we don't know that b can be
                          // a derived class

考虑到您的上下文,我认为您面临的基本问题是通知编译器,
派生的
对象集在
操作符+
下关闭。我知道,你知道,但是C++语言中没有特殊的快捷方式来表达它。您确实需要实现
Derived::operator+(const-Derived&)const


我可能会使
派生(const Base和other)
构造函数
显式
。如果
other
的维度错误,它可能会抛出一个异常,因此用户不应该期望隐式发生这种情况。他们需要知道这是正确的,所以他们可能不得不说他们希望它发生。

不相关的挑剔:你确定
scale
应该返回一个参考吗?@SteveJessop为什么不??规模可以“返回这个”,以避免复制。@ Matthais:啊,愚蠢的我,我没有想到<代码>比例<代码>可能是一个突变。我新的不相关的挑剔是
操作符+
应该是
常量
成员函数!我认为建议
template float super_math_wizarry(const T&T){return Derived(T).super_math_wizarry()}
是不受欢迎的,因为这些派生函数实际上有很多,所以你不希望每个函数都有很多样板,就像你希望
Base
中的每个函数都有很多样板一样?但是,
Derived
有一个
Base
构造函数这一事实是不寻常的。它向我建议,
Derived
不添加数据成员,因此可以将
super\u math\u wizary
定义为自由函数,而不是一开始的成员函数,我做了一些编辑,以使它更清楚我在寻找什么,并提供一些上下文。这是一个令人不快的问题,因为在我的应用程序中,我担心代码覆盖率,所以这将使我的测试用例几乎翻倍。谢谢你们所有人的帮助。@user1445306:好吧,也许你们可以欺骗一下你们的测试方法。将案例{assert(case.left+case.right==case.result)}中案例的
更改为案例{assert(case.left+case.right==case.result);if(case.result.cols==1)assert(派生的(case.left)+派生的(case.right)==派生的(case.result);}
。然后,您的行覆盖率指标将告诉您测试用例是否实际包含任何单列矩阵,这可能值得知道,即使有一些聪明的方法可以实现您的目的。是的,它是并行测试两个代码单元,而不是一个。Sue me;-)
Base* b1 = new Base();
b1->super_math_wizardry(); // This is just plain wrong