2016-03-19 6 views
2

Могу ли я указывать значения по умолчанию одновременно, как в МЕТОДЕ 1, или использовать перегруженный конструктор, как в МЕТОДЕ 2, или с списком инициализации, как в МЕТОДЕ 3/4?Значения по умолчанию аргументов в конструкторе C++

Какой способ лучше/правильно и почему (все они работают)?

И какова разница между МЕТОДОМ 3 и 4 - следует ли указывать объявление первого конструктора, а затем следующее определение вне класса или я могу сразу определить определение?

СПОСОБ 1:

#include <iostream> 
#include <string> 
using namespace std; 
const string GLOBAL_VAR = "XXX"; 

class Object 
{ 
private: 
    string var; 

public: 
    Object(string inArg = "yyy") 
    { 
     this->var = GLOBAL_VAR + inArg + "ZZZ"; 
    } 

    string show() 
    { 
     return this->var; 
    } 
}; 


int main() { 
    Object o1, o2("www"); 
    cout << o1.show() << endl; 
    cout << o2.show() << endl; 

    system("pause"); 
} 

СПОСОБ 2:

#include <iostream> 
#include <string> 
using namespace std; 
const string GLOBAL_VAR = "XXX"; 

class Object 
{ 
private: 
    string var; 

public: 
    Object() 
    { 
     this->var = GLOBAL_VAR + "yyyZZZ"; 
    } 

    Object(string inArg) 
    { 
     this->var = GLOBAL_VAR + inArg + "ZZZ"; 
    } 

    string show() 
    { 
     return this->var; 
    } 
}; 


int main() { 
    Object o1, o2("www"); 
    cout << o1.show() << endl; 
    cout << o2.show() << endl; 

    system("pause"); 
} 

СПОСОБ 3:

#include <iostream> 
#include <string> 
using namespace std; 
const string GLOBAL_VAR = "XXX"; 

class Object 
{ 
private: 
    string var; 

public: 
    //declaration: 
    Object(); 
    Object(string); 

    string show() 
    { 
     return this->var; 
    } 
}; 
//definition: 
Object::Object() : var(GLOBAL_VAR + "yyyZZZ") {} 
Object::Object(string inArg) : var(GLOBAL_VAR + inArg + "ZZZ"){} 


int main() { 
    Object o1, o2("www"); 
    cout << o1.show() << endl; 
    cout << o2.show() << endl; 

    system("pause"); 
} 

МЕТОД 4:

#include <iostream> 
#include <string> 
using namespace std; 
const string GLOBAL_VAR = "XXX"; 

class Object 
{ 
private: 
    string var; 

public: 
    //declaration and definition in one: 
    Object() : var(GLOBAL_VAR + "yyyZZZ") {} 
    Object(string inArg) : var(GLOBAL_VAR + inArg + "ZZZ") {} 

    string show() 
    { 
     return this->var; 
    } 
}; 


int main() { 
    Object o1, o2("www"); 
    cout << o1.show() << endl; 
    cout << o2.show() << endl; 

    system("pause"); 
} 
+1

В C++ вам не нужна нотация 'this->'. Получите доступ к переменным-членам напрямую. –

+1

Разница между методом 2 и 3. Разница между методом 2 и 4 заключается в том, что один использует списки инициализаторов, а другой нет. Это означает, что методы 2, 3 и 4 одинаковы. Что касается того, что является «лучшим», это зависит от того, что вы думаете, это субъективно и мнение. –

ответ

1

Я считаю, оба подхода одинаково справедливы. В зависимости от особенностей каждого отдельного класса каждый подход имеет свои преимущества, сильные и слабые стороны.

Использование значения по умолчанию, как правило, является наилучшим выбором, когда объект должен быть инициализирован практически так же, независимо от того, установлен ли параметр конструктора по умолчанию. Указание значения по умолчанию не позволяет дублировать кучу кода. У вас есть только один конструктор.

С другой стороны, использование перегруженных конструкторов позволяет полностью конструировать объект по-разному, в зависимости от того, задан ли параметр или нет. Принуждение класса к одному конструктору обычно приводит к тому, что в этом случае ковер закладывает код с кучей if.

Кроме того, не забывайте о третьем варианте: делегирующий конструктор. Использование класса в вашем примере кода:

Object() : Object("") 
{ 
} 

Этот подход имеет свои собственные неотъемлемые преимущества.

Нет единого мнения о том, какой подход лучше всего в целом. Лучше всего учитывать индивидуальные требования каждого класса и выбирать подход, который лучше всего подходит для этого класса. Что лучше для одного класса, возможно, не лучший способ для другого класса.

+0

В соответствии с конструктором делегирования, который лучше: 'Object (string inArg =" yyy "): var (inArg) {var = GLOBAL_VAR + var +" ZZZ "; } 'или' Object(): Object ("yyy") {} Объект (строка inArg): var (inArg) {var = GLOBAL_VAR + var + "ZZZ"; } '? – BlueMark

+0

В этом конкретном случае я считаю, что подход-конструктор делегирования лучше, по крайней мере, с использованием компилятора. Но только для этого конкретного класса. Этот вывод применим только к этому классу, и никакого другого класса.Другими словами: это очень мало. и это не должно интерпретироваться как означающее, что конструктор делегирования будет лучше в каком-то другом классе или другом компиляторе. Знание и понимание использования каждого из ваших классов и вашего компилятора требуется для того, чтобы получить правильный вывод по этой теме для данного класса. –