【问题标题】:overloading *, +, -'operators for vector<double> class重载 *、+、-'vector<double> 类的运算符
【发布时间】:2013-01-03 10:04:34
【问题描述】:

我正在编写一个 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 类中重载此类运算符?我应该只制作函数(或方法)而不是运算符吗?还有其他建议吗?

ps1:我使用 Visual Studio 11 作为编译器。

ps2:我没有将项目启动为“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

【问题讨论】:

  • std::vector 继承是一个非常糟糕的主意。此外,您从未定义过您的 ctor/dtor。
  • 那我应该只做函数,还是你有别的想法?
  • 最好只坚持标准容器的组合。
  • 算子没问题,但要使用聚合。

标签: c++ class operator-overloading stdvector


【解决方案1】:

您必须在全局范围内重载运算符:

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 构造函数和析构函数。

【讨论】:

  • 在我不请自来的意见中,重载只接受不属于您自己类型的参数的运算符并不是一个好主意,特别是在全局范围内,其他一些愚蠢的库可能已经完成了一样。
  • @BenjaminLindley 是的,这就是标准明确禁止它的原因 - 模板必须首先使用用户类型进行参数化。
【解决方案2】:

你永远不应该从std-classes 继承那些不是用来继承的。从没有虚拟析构函数的类继承是非常危险的。

我建议您使用聚合:让您的 Line 类包含 vector 类型的成员,例如名为 myVector_,并以使用此成员变量的方式实现所需的运算符。

因此,您将对 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... 才能让它工作。 ty for ctor/dtor 我不知道。
  • 这到底是什么意思? return myVector_[i];如果函数的返回类型正确应该没问题
  • 或者您的意思是要访问内部数组?如果您使用 C++ 11,请使用 &amp;myVector_[0]myVector_.data()
【解决方案3】:

链接器错误告诉您,您的代码缺少您声明的两个成员函数的定义 - 构造函数和析构函数:

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

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

【讨论】:

    【解决方案4】:

    当然正确的做法是在行内有一个 Vector 对象,而不是从 Vector 中“继承”?通常从std:: 容器继承不是一个很好的数据......我很确定“线”实际上不是一个向量,它是一个“有一个”向量。 [“当你继承”的规则是“X 是一个 Y”,当“X 有一个 Y”时,你会创建一个复合对象——所以 X 里面有一个 Y。]

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

    我还会使用 const Line&amp; 作为数学运算的输入,因为您永远不会更改输入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-10
      • 1970-01-01
      • 2011-05-03
      • 2018-12-16
      • 1970-01-01
      • 2019-09-12
      相关资源
      最近更新 更多