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 внутри основного или с помощью функции члена класса.

Может ли кто-нибудь помочь мне? Я использую Visual Studio 2015

+1

Этот класс также потребуется перегрузить некоторые функции для размещения копирования. Этот пост должен быть полезен: https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three – Galik

ответ

2

петли никогда не вводятся, потому что

i < g.size 

всегда false, потому что g.size это 0! Вы никогда не устанавливаете переменную-член size на размер, введенный пользователем, поэтому он по умолчанию равен 0.

Вы должны установить его, то есть

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

Кроме того, вы не указали конструктор копирования, так что неявное один будет использоваться. Но неявный просто копирует значения, и поэтому указатель grph укажет на 2 объекта на одни и те же данные. Вы теряете память, поэтому не имеет значения (технически), но вы должны реализовать правильный деструктор и скопировать/переместить конструктор.

но т.к.

+0

Хотя это правда, это только часть проблемы. Посмотрите на подпись оператора, а затем посмотрите на то, что OP для класса. – NathanOliver

+0

@NathanOliver Я этого не вижу. Они же? – Rakete1111

+0

OP делает копию. У них есть копия c'tor? – NathanOliver

0

Проблема связана с пропущенной инициализацией атрибута класса size в методе costructor.

Добавление к вашему 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- code-based -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; 
    } 
    
Смежные вопросы