【问题标题】:C++ how to create double class operator [][] [duplicate]C++如何创建双类运算符[][] [重复]
【发布时间】:2015-01-02 14:53:18
【问题描述】:

我正在构建一种能够管理矩阵的类型,所以我已经搜索了如何制作 [][] 运算符,但没有运气,所以知道如何做到这一点,我只需要一种制作双运算符的方法 这是正在建设的班级

#include<iostream>
#include<conio.h>

using namespace std;

class ddouble{
private:
unsigned short int  x, y;
public:
ddouble();
ddouble(unsigned short int, unsigned short int);
double **M;
void read();
void print();
};

ddouble::ddouble(unsigned short int m, unsigned short int n){
for (int i = 0; i < m; i++){
    M = new (nothrow) double *[i];
    for (int I = 0; I < n; I++){
        M[i] = new (nothrow) double[I];
    }
}
}
void ddouble::read(){
for (int i = 0; i < x; i++){

    cout << "plz enter line \n";

    for (int I = 0; I < y; I++){
        cin >> M[i][I];
    }
}
}
void ddouble::print(){

cout << "i,j\t|\t";

for (int i = 0; i < y; i++){
    cout << i << "\t";
}

cout << endl;

for (int i = 0; i < x; i++){

    cout << i << "\t|\t";

    for (int I = 0; I < y; I++){
        cout << M[i][I] << "\t";
    }

    cout << endl;
}
} 

void main(){

ddouble a(2, 2);
a.read();
a.print();

_getch();
}

【问题讨论】:

标签: c++


【解决方案1】:

我建议使用std::vector&lt;std::vector&lt;double&gt;&gt;。也就是说,鉴于您现在拥有的结构,您可以简单地定义一个返回 double *operator[],例如:

double * ddouble::operator[](int i) {
    return M[i];
}

您现在可以以a[i][j] 的身份访问main 中的变量。

此外,您还缺少一个释放内存的析构函数;没有它你有内存泄漏。您应该将析构函数定义为:

void ddouble::~ddouble() {
    for(int I = 0; I < y; I++) {
        delete [] M[I];
    }

    delete [] M;
}

【讨论】:

  • thnx 成功了:3
  • @wolfPack88 : 你能告诉我们既然我们已经通过应用循环删除了内存,为什么我们需要再次调用delete [] M;
  • @Unbreakable: M 是指向一系列指针的指针,每个指针在循环中都以M[I] 的形式访问。每个指针也分配了一些内存,这就是我们在循环中的delete-ing。在循环之后,我们有delete-ed 指针的内存,我们需要delete 指向指针的指针,或者M
  • 所以我们总共有 y+1 个指针。有点..
【解决方案2】:

就个人而言,我不会。我会采用简单的选项,并提供一个接受两个参数的函数(或可能的 operator())。

如果你真的想支持[][] 语法,那么你需要第一次调用来返回一些代理类型,它也会重载operator[] 来给出最终结果。这将沿着

class proxy {
    double * p;
public:
    proxy(double * p) : p(p) {}
    double & operator[](size_t i) {return p[i];}
};

proxy operator[](size_t i) {return proxy(M[i]);}

为 const 正确性添加必要的重载留作练习。

在这个简单的例子中,代理可能只是一个double* 指针;如果访问更复杂,或者您想添加边界检查或其他访问控制,则需要一个类。

(和往常一样,当您编写资源管理类时,不要忘记Rule of Three)。

【讨论】:

  • 您是否有理由更喜欢 proxy 类而不是仅仅返回 double *
  • @wolfPack88 proxy 可以支持检查越界访问。
  • @wolfPack88:好点;在这种情况下,指针就可以了。如果访问比简单的数组索引更复杂,则需要一个类。
【解决方案3】:

您可以实现代理类来提供该行为。粗略的草图类似于:-

template<class T>
class Array2D 
{
  public:
    class Array1D 
    {
      public:
        T& operator[](int index);
        const T& operator[](int index) const;
        ...
    };
    Array1D operator[](int index);
    const Array1D operator[](int index) const;
    ...
};

此类的客户端不知道内部代理对象。我建议你去std::vector&lt;std::vector&lt;double&gt; &gt;。但是在某些情况下,您希望汇总自己的类来为客户要求提供特定行为,例如边界检查等...

【讨论】:

  • 我对此投了反对票,因为 1- 你使用了 Scott Meyers 的《更有效的 C++》中的这个片段,而你没有做任何参考。 2 - 这个“粗略的草图”不是 OP 想要的。
猜你喜欢
  • 2022-01-11
  • 2011-10-07
  • 2012-06-21
  • 1970-01-01
  • 2015-02-27
  • 1970-01-01
  • 2020-10-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多