2015-06-06 3 views
1

Я начинаю с C++, поэтому в моем сознании много непонятных вещей.Конструкторы классов в C++

У меня этот код мне нужно написать, и в классе я создаю конструктор. Однако мне не нужны какие-либо параметры, потому что я прочитал из файлового потока внутри конструктор. Так что мои вопросы:

1.Can Я делаю конструктор так:

class myClass { 
private: 
    string title; 
    string organizer; 
public: 
    myClass() { 
    title = stringRead(); 
    organizer = stringRead(); 
    } 
} 

где stringRead() является функцией я написал, чтобы читать из моего файла ??

2. Как я могу назвать это впоследствии, когда мне это нужно? Я знаю, что конструктор по умолчанию вызывается вот так:

myClass A; 
A = myClass(); 

Это то же самое?

3.Если у меня есть указатель, как я могу вызвать конструктор снова? Это не похоже, что это должно быть правильно ...

myClass *B; 
B = myClass(); 

Заранее благодарен! = D

+0

Проблема с stringRead является , похоже, нет различия между титулом и организатором. Они в основном будут получать одинаковое значение. Я бы не реализовал их внутри такого конструктора, возможно, в сеттер. –

+0

Полезное чтение: см. Раздел «Конструкторы» в http://www.cplusplus.com/doc/tutorial/classes/ – jarmod

ответ

2

1) Этот конструктор будет работать, но вы Shoul d одолжение, используя список инициализации (предполагается, что stringRead() не является функцией членом myClass

class myClass { 
private: 
    string title; 
    string organizer; 
public: 
    myClass() 
    : title(stringRead()), 
     organizer(stringRead()) 
    { } 
}; 

2) myClass A; является то, что вы должны делать. В качестве альтернативы вы можете использовать auto A = myClass();, который после оптимизации будет одним и тем же. Без оптимизации временной будет построен, а затем A будет двигаться построенный из него, так что это не будет работать с неподвижными объектами (ваш объект подвижна)

3) Если вы хотите использовать сырой указатель, то вы бы использование

myClass *ptr = new myClass; 
// bunch of code 
delete ptr; 

Однако, вам лучше использовать интеллектуальный указатель для контроля его срока службы. Таким образом, вам не нужно будет вручную удалить

std::unique_ptr<myClass> ptr(new myClass); 

или make_unique в C++ 14

auto ptr = std::make_unique<myClass>(); 

И, конечно, использовать shared_ptr если вы долевой собственности

+0

около 2: У меня есть класс в классе, поэтому мне нужно написать 'class myClass1: private: myClass2 element; public: myClass1() {/ * конструктор вызовов myClass2 * /} ' – Anina7

+0

@ Anina7 Я не понимаю –

+0

проверьте его снова. Я ударил «введите» по ошибке, прежде чем писать. =] – Anina7

1
  1. Ваш конструктор в порядке, если функции, используемые в нем, являются глобальными или статическими функциями этого или другого класса.

  2. myClass A; вызовет созданный вами конструктор.

  3. Чтобы использовать указатель, вам понадобится B = новый myClass(). Это также вызовет тот же конструктор. Не забудьте удалить B в какой-то момент, иначе вы будете утечка памяти.

Имейте в виду, что если исключение выбрано в конструкторе, деструктор не вызывается.

1

Я думаю, что это нормально, чтобы присвоить значение, возвращаемое функцией, члену класса.

Вы можете инициализировать его, как вы предложили (с myClass A;)

При использовании указателей, вам нужно myClass *k=new myClass();. Не забудьте удалить созданный объект с помощью delete k;.

1
  1. Да, вы можете, но это может быть не лучший подход. Чтение с входа может завершиться неудачно, сбой в конструкторе часто является невосстанавливаемым событием, которое вы хотите обработать. Хороший подход - считывание значений вне бизнес-структур, обработка ошибок и вызов конструктора только тогда, когда у вас есть «все готово».Как это:

    class myClass { 
    private: 
    string _title; 
    string _organizer; 
    public: 
        myClass(const string &title, const string &organizer) { 
        _title = title; 
        _organizer = organizer; 
    } 
    

    или, используя более идиоматических C++ список инициализатора:

    class myClass { 
    private: 
    string _title; 
    string _organizer; 
    public: 
        myClass(const string &title, const string &organizer): 
        _title(title), _organizer(organizer) {} 
    } 
    

    , а затем, где-то еще:

    string title = stringRead(); 
    string organizer = stringRead(); 
    myClass A(title, organizer); 
    
  2. Нет, в этом фрагменте:

    myClass A; 
    A = myClass(); 
    

    два разных все происходит: в строке 1 вызывается конструктор по умолчанию; в строке 2 создается временный объект (опять же, вызывая конструктор по умолчанию), а затем назначается A с использованием оператора копирования (rval для C++ 11). Это выражение:

    myClass A; 
    

    вызывает конструктор по умолчанию. Если у вас есть параметры:

    myClass A(title, organizer); 
    
  3. Нет, это даже не работает. Указатель не является объектом, вы должны выделить объект. В этот момент, вы можете получить указатель на него:

    myClass A; 
    myClass *B = &A; 
    

    можно также прибегнуть к динамическому распределению:

    myClass *B = new myClass; 
    

    в этом случае, либо не забудьте позвонить delete B где-то еще или обернуть B в смарт-указатель:

    std::unique_ptr<myClass> B(new myClass()); 
    
+1

, ваш конструктор добавляет ведущие символы подчеркивания для элементов данных, и это конструктор java-стиля. Вы должны использовать список инициализации. –

+0

@RyanHaining список инициализаторов, безусловно, более идиоматичен, но может быть непонятным для истинного начинающего, такого как OP. Во всяком случае, я добавил оба. –

Смежные вопросы