2013-03-29 50 views
7

Tôi đã xem xét một vài câu hỏi khác về điều này, nhưng tôi không thấy lý do tại sao một hàm tạo mặc định thậm chí nên được gọi trong trường hợp của tôi. Tôi chỉ có thể cung cấp một hàm tạo mặc định, nhưng tôi muốn hiểu tại sao nó lại làm điều này và nó ảnh hưởng đến cái gì."Không có hàm tạo mặc định phù hợp nào" - Tại sao hàm tạo mặc định được gọi?

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

Tôi có một lớp được gọi là ProxyPiece với một biến thành viên của CubeGeometry.Các nhà xây dựng có nghĩa vụ phải thực hiện trong CubeGeometry và gán nó cho biến thành viên. Đây là tiêu đề:

#pragma once 
#include "CubeGeometry.h" 

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

và nguồn:

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

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


ProxyPiece::~ProxyPiece(void) 
{ 
} 

tiêu đề cho hình khối trông như thế này. Nó không có ý nghĩa với tôi để sử dụng một constructor mặc định. Tôi cần nó anyways ?:

#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; 
}; 

Trả lời

22

constructor mặc định của bạn là mặc nhiên được gọi ở đây:

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

Bạn muốn

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

} 

Nếu không ctor của bạn là tương đương với

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

Điều sau đại tràng được gọi là memberinitialization list.

Ngẫu nhiên, tôi sẽ lấy đối số là const CubeGeometry& c thay vì CubeGeomety& c nếu tôi là bạn.

+3

Để rõ ràng hơn, có lẽ bạn có thể, trong đoạn "giống như", thay đổi 'cube = c;' thành 'cube.operator = (c);'. Nó sẽ giúp giải thích rằng nhiệm vụ không (từ góc độ ngôn ngữ) tái khởi tạo 'khối lập phương'. – hvd

+0

@hvd: đã đồng ý, chỉnh sửa –

+0

Vì vậy, tất cả các hàm tạo mặc định của bất kỳ biến thành viên nào được gọi trước hàm tạo cho lớp chứa? (và có, tôi sẽ làm cho nó một const :)) – AAB

4

Khởi tạo thành viên xảy ra khi hàm khởi tạo bắt đầu. Nếu bạn không cung cấp một bộ khởi tạo trong danh sách khởi tạo thành viên của hàm tạo, thành viên sẽ được xây dựng mặc định. Nếu bạn muốn sao chép constructor sẽ được sử dụng để khởi tạo thành viên cube, sử dụng danh sách thành viên khởi tạo:

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

Tất cả mọi thứ sau đại tràng là danh sách khởi tạo. Điều này chỉ đơn giản nói rằng cube nên được khởi tạo với c.

Như bạn đã làm, thành viên cube lần đầu tiên được khởi tạo mặc định và sau đó cbản sao được gán cho nó.

+0

Tôi hiểu, cảm ơn lời giải thích về danh sách khởi tạo/chuyển nhượng bản sao! – AAB

Các vấn đề liên quan