2016-08-04 75 views
1

这里是类如何重载<<操作符以打印类成员?

class graph { 
    public: 
     graph() {}; // constructor 
     graph(int size); 
     friend ostream& operator<< (ostream& out, graph g); 
    private: 
     int size; 
     bool** grph; 
    }; 

我这是怎么生成的图形:

graph::graph(int size) { 
     grph = new bool*[size]; 
     for (int i = 0; i < size; ++i) 
      grph[i] = new bool[size]; 
     for (int i = 0; i < size; ++i) 
      for (int j = i; j < size; ++j) { 
       if (i == j) 
        grph[i][j] = false; 
       else { 
        cout << prob() << endl;//marker 
        grph[i][j] = grph[j][i] = (prob() < 0.19); 
        cout << grph[i][j] << endl;//marker 
       } 
      } 
     cout << "Graph created" << endl;//marker 
    } 

构造函数和概率()函数的工作就好了。我已经使用标记测试了它们。

这是我认为存在问题的地方。这是重载操作< <

ostream& operator<< (ostream& out, graph g) { 
     for (int i = 0; i < g.size; ++i) { 
      for (int j = 0; j < g.size; ++j) 
       out << g.grph[i][j] << "\t"; 
      out << endl; 
     } 
     return out; 
    } 

代码下面是这是怎么叫。

 graph g(5); 
cout << g << endl; 

现在,程序编译就好了。但是,执行时,图形不会被打印。我已经能够以相同的方式打印图形而不会重载运算符,但是可以通过让for循环在main中运行或使用类成员函数来运行。

任何人都可以帮我吗?我使用Visual Studio 2015年

+1

这个类也将需要重载一些功能,以适应复制。这篇文章应该是有用的:https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three – Galik

回答

2

的环路从未进入,因为

i < g.size 

总是false,因为g.size0!你永远不会将成员变量size设置为用户输入的大小,所以它默认为0

你必须设置,即

this->size = size; //Sets member variable 'size' to 'size' from the function arguments 

而且,你没有指定一个拷贝构造函数,所以隐含的一个将被使用。但是隐式的只是复制这些值,因此指针grph会将2个对象指向相同的数据。你正在泄漏内存,这就是为什么它不重要(技术上),但你应该实现一个适当的析构函数和复制/移动构造函数。

但是因为operator<<应该只打印,考虑通过const&而不是价值!

+0

虽然这只是问题的一部分。看看操作员的签名,然后看看OP对班级的信息。 – NathanOliver

+0

@NathanOliver我看不到它。他们一样吗? – Rakete1111

+0

该OP正在复制。他们有一个副本c'tor? – NathanOliver

0

问题取决于在构造函数方法中丢失的类属性size 的初始化。

添加到您的ctor this.size = size应该解决您的问题,正如Rakete1111已正确指出。

下面的方法允许您打印或真或假,否则你可能会尝试cout<<std::boolalpha标志

ostream& operator<< (ostream& out, graph g) { 
     for (int i = 0; i < g.size; ++i) { 
      for (int j = 0; j < g.size; ++j) 
       out << (g.grph[i][j] ? "true" : "false") << "\t"; 
      out << endl; 
     } 
     return out; 
    } 
+1

虽然这段代码可以解决问题,[包括解释](http://meta.stackexchange.com/questions/114762/explaining-entirely-基于代码-answers)确实有助于提高您的帖子的质量。请记住,您将来会为读者回答问题,而这些人可能不知道您的代码建议的原因。 – NathanOliver

+0

我看到了更好的你的构造函数,实际上原因是“大小”属性错过了初始化...... –

0

除了别人怎么说(你是不是初始化size成员),你operator<<是接受对象按值。当操作员被呼叫时,将输入对象的副本,但您的类未正确写入以支持复制。你operator<<应常引用代替不需要拷贝接受对象

ostream& operator<< (ostream& out, const graph &g) 

你类不支持复制,因为你是完全违反Rule of Three

  1. 你默认的构造函数根本不初始化图形数据。

  2. 您缺少释放图形数据的析构函数。

  3. 您错过了复制构造函数和复制赋值操作符以将图形数据从一个对象复制到另一个对象。

即使你通过引用传递对象operator<<,你仍然需要正确地贯彻执行三的规则,以避免在一般的代码中的问题。

您需要:

  1. 实施适当的建设者和运营商:

    class graph { 
    public: 
        graph(int size = 0); 
        graph(const graph &src); 
        ~graph(); 
    
        graph& operator=(const graph &rhs); 
    
        friend std::ostream& operator<< (std::ostream& out, const graph &g); 
    private: 
        int size; 
        bool** grph; 
    }; 
    
    std::ostream& operator<< (std::ostream& out, const graph &g); 
    

    graph::graph(int size) 
        : grph(NULL), size(size) 
    { 
        grph = new bool*[size]; 
        for (int i = 0; i < size; ++i) { 
         grph[i] = new bool[size]; 
        } 
        for (int i = 0; i < size; ++i) { 
         for (int j = i; j < size; ++j) { 
          if (i == j) { 
           grph[i][j] = false; 
          } else { 
           grph[i][j] = grph[j][i] = (prob() < 0.19); 
          } 
         } 
        } 
    } 
    
    graph::graph(const graph &src) 
        : grph(NULL), size(src.size) 
    { 
        grph = new bool*[size]; 
        for (int i = 0; i < size; ++i) { 
         grph[i] = new bool[size]; 
         for (int j = i; j < size; ++j) { 
          grph[i][j] = src.grph[i][j]; 
        } 
    } 
    
    graph::~graph() { 
        for (int i = 0; i < size; ++i) { 
         delete[] grph[i]; 
        } 
        delete[] grph; 
    } 
    
    graph& graph::operator=(const graph &rhs) 
    { 
        if (this != &rhs) 
        { 
         graph tmp(rhs); 
         std::swap(grph, tmp.grph); 
         std::swap(size, tmp.size); 
        } 
        return *this; 
    } 
    
    std::ostream& operator<< (std::ostream& out, const graph &g) { 
        for (int i = 0; i < g.size; ++i) { 
         for (int j = 0; j < g.size; ++j) { 
          out << g.grph[i][j] << "\t"; 
         } 
         out << endl; 
        } 
        return out; 
    } 
    
  2. 变化使用std::vector,而不是手动分配的数组。让编译器处理所有的内存管理和复制的你:

    class graph { 
    public: 
        graph(int size = 0); 
        friend ostream& operator<< (ostream& out, const graph &g); 
    private: 
        std::vector<std::vector<bool> > grph; 
    }; 
    
    std::ostream& operator<< (std::ostream& out, const graph &g); 
    

    graph::graph(int size) 
    { 
        grph.resize(size); 
        for (int i = 0; i < size; ++i) { 
         grph[i].resize(size); 
        } 
        for (int i = 0; i < size; ++i) { 
         for (int j = i; j < size; ++j) { 
          if (i == j) { 
           grph[i][j] = false; 
          } else { 
           grph[i][j] = grph[j][i] = (prob() < 0.19); 
          } 
         } 
        } 
    } 
    
    ostream& operator<< (ostream& out, const graph &g) { 
        for (int i = 0; i < g.grph.size(); ++i) { 
         std:::vector<bool> &row = g.grph[i]; 
         for (int j = 0; j < row.size(); ++j) { 
          out << row[j] << "\t"; 
         } 
         out << endl; 
        } 
        return out; 
    }