为vector<double>类重载*、+、-运算符

5

我正在编写一个Line类,用于数值计算方法,并希望使用这些运算符(*、+、-)使我的代码更易读和理解。

        #include <vector>

        using namespace std;

        typedef vector<double> Vector;

        class Line : public Vector
        {
        public:
            Line();
            ~Line();

            Line operator+(Line);
            Line operator-(Line);
            Line operator*(double);
        };


        Line Line::operator*(double alfa)
        {
            Line temp;
            int n = size();
            temp.resize(n);
            for (int i = 0; i < n; i++)
            {
                temp.at(i) = this->at(i)*alfa;
            }
            return temp;
        }

        Line Line::operator+(Line line)
        {
            int n = size();
            Line temp;
            temp.resize(n);
            for (int i = 0; i < n; i++)
            {
                temp.at(i) = this->at(i) + line[i];
            }
            return temp;
        }

        Line Line::operator-(Line line)
        {
            int n = size();
            Line temp;
            temp.resize(n);
            for (int i = 0; i < n; i++)
            {
                temp.at(i) = this->at(i) - line[i];
            }
            return temp;
        }


        int main()
        {
            return 0;
        }

能否从Vector类重载这些运算符?我应该使用函数(或方法)而不是运算符吗?还有其他建议吗?

附注1:我使用Visual Studio 11作为编译器。

附注2:我没有将项目开始为“win32项目”,它是控制台应用程序。

我遇到了以下错误:

Error   1   error LNK2019: unresolved external symbol "public: __thiscall Line::Line(void)" (??0Line@@QAE@XZ) referenced in function "public: class Line __thiscall Line::operator*(double)" (??DLine@@QAE?AV0@N@Z) C:\Users\Lucas\Documents\Visual Studio 11\Projects\test\test\test.obj   test


Error   2   error LNK2019: unresolved external symbol "public: __thiscall Line::~Line(void)" (??1Line@@QAE@XZ) referenced in function "public: class Line __thiscall Line::operator*(double)" (??DLine@@QAE?AV0@N@Z)    C:\Users\Lucas\Documents\Visual Studio 11\Projects\test\test\test.obj   test

3
继承自std::vector是一个非常糟糕的想法。此外,您从未定义过您的构造函数/析构函数。 - chris
我应该只是做函数,还是你有其他的想法? - Lucas Da Rocha Souza
1
通常最好只使用组合来处理标准容器。 - chris
运算符没问题,但使用聚合更好。 - lethal-guitar
使用像Boost.uBLAS这样已经具备所有功能的库,不要重复造轮子。 - Philipp
2
你看过 http://en.cppreference.com/w/cpp/header/valarray 吗? - rici
4个回答

7

你需要在全局范围内重载运算符:

vector<double> operator*(const vector<double>& v, double alfa)
{
    ...
}

vector<double> operator+(const vector<double>& v1, const vector<double>& v2)
{
    ...
}

vector<double> operator-(const vector<double>& v1, const vector<double>& v2)
{
    ...
}

关于链接器错误,看起来你没有实现Line构造函数和析构函数。

1
在我未被询问的意见中,如果只接受非自己类型参数的运算符被重载,特别是在全局范围内,这并不是一个好主意,因为其他一些愚蠢的库可能已经做了同样的事情。 - Benjamin Lindley
@BenjaminLindley 是的,这就是为什么标准明确禁止 - 模板必须首先使用用户类型进行参数化。 - user1143634

2

您不应该从不适用于继承的std类中继承。从没有虚析构函数的类继承是非常危险的。

我建议您使用聚合:让您的Line类包含一个名为myVector_vector类型成员,并以一种方式实现所需的运算符,使它们使用这个成员变量。

因此,您将所有对size()的调用替换为myVector.size()等:

Line Line::operator*(double alfa)
{
    Vector temp;
    int n = myVector_.size();
    temp.resize(n);
    for (int i = 0; i < n; i++)
    {
        temp.at(i) = myVector_.at(i)*alfa;
    }
    return temp;
}

我也尝试过,但主要问题在于[]运算符,我无法使其返回指针。 例如: A[i][j] = something.... 不起作用, 我必须输入类似以下的内容: A[i].v.at(j) = something... 才能使其正常工作。 感谢您提供的构造函数/析构函数信息,我之前并不知道。 - Lucas Da Rocha Souza
你的意思是什么?如果函数的返回类型正确,return myVector_[i]; 应该没有问题。 - lethal-guitar
或者你是想访问内部数组?只需使用&myVector_[0]或者如果你使用C++ 11,可以使用myVector_.data() - lethal-guitar

1
链接错误告诉您,您的代码缺少您声明的两个成员函数的定义 - 构造函数和析构函数:
Line::Line() {
    // Code of the constructor goes here
}

Line::~Line() {
    // Code of the destructor goes here
}

0

正确的做法是在Line内部拥有一个Vector对象,而不是从Vector继承。通常从std::容器继承并不是一个好的数据...我非常确定“Line”实际上不是一个向量,它是一个“具有”向量。[“当你继承时”的规则是“X是Y”,当“X有一个Y”时,你创建一个组合对象 - 因此X内部有一个Y。]

您需要声明构造函数和析构函数以消除链接错误。

我还会使用const Line&作为您的数学运算输入,因为您从未更改输入。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接