2013-02-17 16 views
5

W moim kodzie robię co następuje, ale nie jestem pewien, czy jestem "dozwolony", czy jest to dobra technika projektowania. Potrzebuję utworzyć pusty konstruktor, ale potrzebuję także konstruktora, który inicjalizuje zmienne z uwzględnieniem parametrów. Wykonuję następujące czynności:Puste konstruktory w C++:

To jest plik C.h.

class C 
{ 
    private: 
    string A; 
    double B; 
    public: 
    //empty constructor 
    C(); 
    C(string, double); 
} 

A mój plik C.cpp:

//this is how I declare the empty constructor 
C::C() 
    { 

    } 


    C::C(string a, double b) 
    { 
     A = a; 
     B = b; 
    } 

jest droga ja deklarowania pusty prawo konstruktora czy muszę ustawić = null i B = 0,0?

+1

Nie próbowałeś go skompilować? – Anil

+0

To działa, kompiluje i uruchamia, oczywiście, po prostu pytam, czy jest to "dozwolone", czy jest to zła technika projektowania. – FranXh

+0

Jeśli kompiluje, to jest dozwolone. dla tego prostego programu nie powinieneś myśleć o aspektach projektowych. – Anil

Odpowiedz

9

Twój pusty konstruktor nie robi tego, co chcesz. Element danych double nie zostanie zainicjalizowany od zera, chyba że zrobisz to sam. std::string zostanie zainicjowany na pusty ciąg znaków.Więc prawidłowa implementacja domyślnego konstruktora byłoby po prostu

C::C() : B() {} // zero-initializes B 

Jeśli chodzi o inne konstruktora, należy preferować listy inicjalizacji:

C::C(const string& a, double b) : A(a), B(b) {} 

inaczej, co robisz jest przypisanie do domyślnych skonstruowane obiekty.

1

Możesz zostawić bez zmian. Możesz to zrobić, ponieważ zarówno domyślnie konstruowane mogą być string i double. Oznacza to, że możesz powiedzieć string foo; i nie otrzymasz żadnych błędów.

Kontrast to z tym, co się dzieje tutaj:

class Bar{ 
    private: 
     Bar(); //Explicitly private; 
}; 
Bar b; 

Tu pojawia się błąd o braku konstruktora Bar::Bar() znajdowane.

Co do tego, czy to dobry pomysł: Trudno powiedzieć, nie znając sytuacji, w której ta klasa będzie używana. Być może rozsądnie jest mieć to w nieskonfigurowanej pozycji. Ale dla wielu klas, na przykład dla klasy reprezentującej plik, zezwolenie na obiekt pliku, który nie wskazuje żadnego pliku, jest oczywiście błędne.

+0

Ale OP najprawdopodobniej chce, aby 'double' był inicjalizowany od zera, czego nie ma w pustym konstruktorze. – juanchopanza

2

A to std::string, nie można ustawić go na NULL, ale można ustawić na pusty łańcuch, a std::string ma domyślny konstruktor, który domyślnie inicjalizuje go na pusty ciąg.

C::C() 
:B(0.0) 
{ 
} 

Może potrzebujesz konstruktora konstruktora z domyślnym parametrem zamiast dwóch elementów?

C(const string& a= "", double b= 0.0) 
: A(a), 
    B(b) 
{ 
} 
0

Robisz to poprawnie i możesz to zobaczyć, kompilując swój kod. Twój domyślny konstruktor zainicjuje ciąg znaków i podwoi go, wywołując domyślne konstruktory. Jeśli zdefiniujesz dowolny konstruktor w klasie, ukryje on dla ciebie domyślny konstruktor utworzony przez kompilator.

Można poprawić swój kod konstruktora pisząc go jak ten

C::C(string a, double b):A(a), b(b) 
{ 
} 
+0

Ale "inicjalizacja" dubletu pozostawi go z nieokreśloną wartością, która nie jest tym, co OP chce. – juanchopanza

3

Jest dobrze, aby to zrobić i opuścić konstruktora pusty, ale należy pamiętać, że pola niezainicjalizowane mają wartość niezdefiniowana. string to klasa i domyślny konstruktor dba o jej inicjalizację, ale double nie jest tutaj inicjowany (w twoim konstruktorze defualt), a jej wartość jest niezdefiniowana (może to być dowolna wartość poprzednio istniejąca w pamięci).

2

Jesteś jedyną osobą, która może odpowiedzieć na to pytanie, ponieważ zależy to od w całości od odnośnie Twoich wymagań dla obiektu konstruowanego domyślnie. Ponieważ nie wspomniałeś o swoich wymaganiach, nie można podać ostatecznej odpowiedzi. Niektórzy ludzie będą domyślali się, że powinieneś zainicjować B na 0, ale decyzja ta powinna być oparta na twoim projekcie, a nie na różnych pojęciach "dobrej" praktyki programistycznej.