2016-08-04 73 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; 
    }