c ++继承:基类中的2次重载运算符+在派生类中无法正常工作

Posted

技术标签:

【中文标题】c ++继承:基类中的2次重载运算符+在派生类中无法正常工作【英文标题】:c++ inheritance: 2 times overloaded operator+ in base class are not working proper in derived class 【发布时间】:2020-05-10 17:45:53 【问题描述】:

我基于 std::valarray 编写了我的泛型类“MyVector”

//myvector.h
#ifndef MYVECTOR_H
#define MYVECTOR_H
#include <valarray>

template <typename T> 
class MyVector

public:
 MyVector(int size)larr.resize(size);
 MyVector<T>& operator=(const MyVector<T>& other) 
    
    this->larr=other.larr;
    return *this;
    
 MyVector<T> operator+ ( const MyVector<T>& rhs);   //body in .cpp file
 template <typename U> 
 MyVector<T> operator+ (const U& val);              //body in .cpp file
protected:
std::valarray larr;

#endif
//myvector.cpp

/*****other code*****/

template <typename T>
MyVector<T> MyVector<T>::operator+ ( const MyVector<T>& rhs)

    MyVector<T> lv; lv.larr = this->larr + rhs.larr;
    return  lv;  


template <typename T>
template <typename U> 
MyVector<T> MyVector<T>::operator+ (const U& val)

    MyVector<T> lv; lv.larr = this->larr + static_cast<T> (val);
    return  lv;  


/*****other code*****/

然后我尝试编写一个派生类DataVector,具有MyVector的所有功能,尤其是我所有的重载运算符。


#ifndef DATAVECTOR_H
#define DATAVECTOR_H
#include "myvector.h"

class dataVector : public MyVector<int>

public:
    dataVector& operator=(const dataVector& other) 
    
        this->larr=other.larr;
        return *this;
    
    using MyVector<int>::operator=;
    using MyVector<int>::operator+;

#endif

当我尝试编译 main.cpp 时,

//main.cpp
#include "datavector.h"
#include "myvector.h"

dataVector datav1(10);
dataVector datav2(10);
dataVector datav3(10);

//if i write:
datav1=datav1 + 10;  //works (gmake and compiler gcc7.5 on ubuntu)
//if i write:
datav3=datav1 + datav2;  //does not work (gmake and compiler gcc7.5 on ubuntu)

我得到这个编译器错误:

myvector.cpp: In instantiation of ‘MyVector<T> MyVector<T>::operator+(const U&) [with U = dataVector; T = int]’:
myvector.cpp:xxx:yy: error: invalid static_cast from type ‘const dataVector’ to type ‘int’
     MyVector<T> lv; lv.larr = this->larr + static_cast<T> (val);

如果我使用 MyVector:MyVector3=MyVector1+MyVector2 效果很好。

谁能帮帮我? 我知道这段代码写得不好,但我还在学习。 谢谢。

【问题讨论】:

***.com/questions/30138023/…>已经有答案了。 @stackoverblast 不,这个问题实际上并没有在基础中重载operator+,而且它也没有模板化,这两者都与本示例相关。 cpp 中的模板代码可疑 你真的想要template &lt;typename U&gt; MyVector&lt;T&gt; operator+ (const U&amp; val);(匹配dataVector)而不是简单的MyVector&lt;T&gt; operator+ (const T&amp; val); 谢谢大家,@Jarod42 我会尝试调整我的 .cpp 代码 【参考方案1】:

问题是当你将MyVector添加到MyVector时,MyVector::operator+ ( const MyVector&lt;T&gt;&amp; rhs)匹配,但是当你添加dataVectordataVector时,dataVector::operator+ (const U&amp; val)(继承自MyVector)变得更好的匹配因为它接受任何东西,不一定是T 可转换的东西。有几种可能的解决方案。

    dataVector 设为typedef,如using dataVector = MyVector&lt;int&gt;,如果合适的话。 添加operator+ 接受dataVector;它可以使用显式强制转换(如*this + (const MyVector&lt;int&gt; &amp;)rhs)调用继承的运算符。 按照 Jarod42 的建议,将 MyVector::operator+ (const U&amp; val) 限制为仅接受 T。 (艰难的方式)限制MyVector::operator+ (const U&amp; val) 仅使用SFINAE(如template &lt;typename U, typename = typename std::enable_if&lt;std::is_arithmetic&lt;U&gt;::value&gt;::type&gt;,或者is_convertible_to,或任何适当的)来接受理智的类型。

【讨论】:

谢谢,感谢@jarod42,为了方便,我添加了typename U,.我不想重写运算符,因为我重载了 +,-,*,/,==。我会尝试第三种解决方案,谢谢您的帮助。

以上是关于c ++继承:基类中的2次重载运算符+在派生类中无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

c++中的虚函数有啥作用?

c++解决二义性的方法

基类 派生类 类的继承与约束

基类中的运算符重载问题

C#防止基类方法被派生类中的new修饰符隐藏

如何从基类中的函数调用重载函数?