2013-03-29 11 views
7

Sprawdziłem kilka innych pytań na ten temat, ale nie widzę powodu, dla którego domyślny konstruktor powinien być wywołany w moim przypadku. Mogę po prostu dostarczyć domyślnego konstruktora, ale chcę zrozumieć, dlaczego to robi i co wpływa."Brak odpowiedniego domyślnego konstruktora" - Dlaczego wywoływany jest domyślny konstruktor?

error C2512: 'CubeGeometry' : no appropriate default constructor available 

Mam klasy o nazwie ProxyPiece ze zmienną członkiem konstruktora CubeGeometry.The ma podjąć w CubeGeometry i przypisać ją do zmiennej członka. Oto nagłówek:

#pragma once 
#include "CubeGeometry.h" 

using namespace std; 
class ProxyPiece 
{ 
public: 
    ProxyPiece(CubeGeometry& c); 
    virtual ~ProxyPiece(void); 
private: 
    CubeGeometry cube; 
}; 

i źródło:

#include "StdAfx.h" 
#include "ProxyPiece.h" 

ProxyPiece::ProxyPiece(CubeGeometry& c) 
{ 
    cube=c; 
} 


ProxyPiece::~ProxyPiece(void) 
{ 
} 

nagłówek dla geometrii kostka wygląda następująco. Nie ma sensu używać domyślnego konstruktora. Czy muszę to jakikolwiek ?:

#pragma once 
#include "Vector.h" 
#include "Segment.h" 
#include <vector> 

using namespace std; 

class CubeGeometry 
{ 
public: 
    CubeGeometry(Vector3 c, float l); 

    virtual ~CubeGeometry(void); 

    Segment* getSegments(){ 
     return segments; 
    } 

    Vector3* getCorners(){ 
     return corners; 
    } 

    float getLength(){ 
     return length; 
    } 

    void draw(); 

    Vector3 convertModelToTextureCoord (Vector3 modCoord) const; 

    void setupCornersAndSegments(); 

private: 
    //8 corners 
    Vector3 corners[8]; 

    //and some segments 
    Segment segments[12]; 

    Vector3 center; 
    float length; 
    float halfLength; 
}; 

Odpowiedz

22

Domyślny konstruktor jest niejawnie nazywany tutaj:

ProxyPiece::ProxyPiece(CubeGeometry& c) 
{ 
    cube=c; 
} 

Chcesz

ProxyPiece::ProxyPiece(CubeGeometry& c) 
    :cube(c) 
{ 

} 

przeciwnym razie konstruktor jest równoważna

ProxyPiece::ProxyPiece(CubeGeometry& c) 
    :cube() //default ctor called here! 
{ 
    cube.operator=(c); //a function call on an already initialized object 
} 

Rzecz po dwukropku nazywa się memberinitialization list.

Nawiasem mówiąc, wziąłbym argument jako const CubeGeometry& c zamiast CubeGeomety& c, gdybym był tobą.

+3

Aby być jeszcze jaśniejszym, być może mógłbyś, w swoim "jest taki sam jak", zmienić 'cube = c;' na 'cube.operator = (c);'. Pomogłoby to wyjaśnić, że przypisanie nie powoduje (z punktu widzenia języka) ponownej inicjalizacji kostki. – hvd

+0

@hvd: uzgodniono, edytowanie –

+0

Tak więc wszystkie konstruktory domyślne dowolnych zmiennych składowych są wywoływane przed konstruktorem do klasy zawierającej? (i tak zrobię to const :)) – AAB

4

Inicjalizacja członka następuje po rozpoczęciu konstruktora. Jeśli nie udostępnisz inicjalizatora na liście inicjalizacji elementu konstruktora, element będzie domyślnie skonstruowany. Jeśli chcesz skopiować konstruktora być wykorzystane do zainicjowania elementu cube, skorzystać z listy inicjalizacji członkiem:

ProxyPiece::ProxyPiece(CubeGeometry& c) 
    : cube(c) 
{ } 

Wszystko po dwukropku jest lista inicjalizacji. To po prostu mówi, że cube należy zainicjować przy pomocy c.

Jak miał, członek cube najpierw domyślną zainicjowany i następnie c została kopię przypisany do niego.

+0

Rozumiem, dziękuję za wyjaśnienie list inicjujących/przypisanie kopii! – AAB