2009-07-14 44 views
244

Có thể struct có một hàm tạo trong C++ không?Cấu trúc Constructor trong C++?

Tôi đã cố giải quyết vấn đề này nhưng tôi không nhận được cú pháp.

+1

Đây là một câu hỏi khủng khiếp không có nghiên cứu nền hoặc ngữ cảnh về những gì không hoạt động. Tại sao nó được đánh giá cao như vậy? –

Trả lời

121
struct TestStruct { 
     int id; 
     TestStruct() : id(42) 
     { 
     } 
}; 
+27

Phần ': id (42)' được gọi là gì? – user13107

+47

@ user13107: "[danh sách khởi tạo] (http://en.cppreference.com/w/cpp/language/initializer_list)" là từ bạn đang tìm kiếm. – Regexident

+4

Điều đó sẽ không có tác dụng nếu bạn kế thừa từ một lớp khác và biến đó được khai báo trong lớp cha. –

349

Trong C++ là sự khác biệt duy nhất giữa một classstruct là thành viên và các lớp cơ sở là tin theo mặc định trong lớp học, trong khi họ là công khai theo mặc định trong cấu trúc.

Các cấu trúc có thể có các hàm tạo và cú pháp giống như đối với các lớp.

+51

Và cấu trúc đó sẽ mặc định cho công chúng khi bắt nguồn từ :) – GManNickG

+2

@sth Quyền của bạn về sự khác biệt giữa cấu trúc và lớp, tuy nhiên tôi nghĩ rằng anh ấy đang gặp vấn đề biên dịch. Vấn đề có thể là do một liên minh đang sử dụng cấu trúc. Bạn không thể có các nhà xây dựng không tầm thường trong loại bạn có trong một công đoàn. – Chap

+2

@Chap: Nếu anh ta có vấn đề cụ thể khi giải pháp chung không hoạt động, có thể là ý tưởng tốt nhất để đăng một số mã cho thấy sự cố và lỗi trình biên dịch được tạo. Nhưng nói chung là câu hỏi được hỏi tôi không nghĩ rằng người ta thực sự có thể phỏng đoán quá nhiều về vấn đề cụ thể mà OP đang cố giải quyết ... – sth

13

Có. Một cấu trúc giống như một lớp học, nhưng mặc định là public:, trong định nghĩa lớp và khi kế thừa:

struct Foo 
{ 
    int bar; 

    Foo(void) : 
    bar(0) 
    { 
    } 
} 

Xét câu hỏi khác của bạn, tôi sẽ đề nghị bạn đọc qua some tutorials. Họ sẽ trả lời các câu hỏi của bạn nhanh hơn và đầy đủ hơn chúng tôi sẽ làm.

10

Có cấu trúc và lớp trong C++ giống nhau ngoại trừ cấu trúc thành viên được công khai theo mặc định trong khi các thành viên lớp học được đặt ở chế độ riêng tư theo mặc định. Bất cứ điều gì bạn có thể làm trong một lớp học, bạn sẽ có thể làm trong một cấu trúc.

struct Foo 
{ 
    Foo() 
    { 
    // Initialize Foo 
    } 
}; 
+0

Loại điều được tạo bởi từ khóa 'struct' _is a class_. –

31

Có, nhưng nếu bạn có cấu trúc trong liên minh thì bạn không thể. Nó giống như một lớp học.

struct Example 
{ 
    unsigned int mTest; 
    Example() 
    { 
    } 
}; 

Công đoàn sẽ không cho phép các nhà thầu trong cấu trúc. Bạn có thể tạo một hàm tạo trên union. This question relates to non-trivial constructors in unions.

1

Trong C++, chúng ta có thể khai báo/xác định cấu trúc giống như lớp và có các hàm tạo/hủy cho cấu trúc và có các biến/hàm được định nghĩa trong nó. Sự khác biệt duy nhất là phạm vi mặc định của các biến/hàm được xác định. Khác với sự khác biệt trên, chủ yếu là bạn sẽ có thể bắt chước các chức năng của lớp bằng cách sử dụng cấu trúc.

12
struct HaveSome 
{ 
    int fun; 
    HaveSome() 
    { 
     fun = 69; 
    } 
}; 

Tôi muốn khởi tạo bên trong trình tạo nên tôi không cần phải giữ lệnh.

+0

Thành viên luôn được khởi tạo theo thứ tự xuất hiện trong lớp/cấu trúc cơ thể. Tạo các bài tập trong phần thân của hàm tạo chỉ là ... các bài tập. –

4

Có thể có nhà xây dựng trong cơ cấu ở đây là một ví dụ:

#include<iostream.h> 
struct a { 
    int x; 
    a(){x=100;} 
}; 

int main() { 
    struct a a1; 
    getch(); 
} 
27

Tất cả các câu trả lời ở trên về mặt kỹ thuật trả lời câu hỏi của Người hỏi, nhưng chỉ cần nghĩ rằng tôi muốn chỉ ra một trường hợp bạn có thể gặp vấn đề.

Nếu bạn khai báo struct của bạn như thế này:

typedef struct{ 
int x; 
foo(){}; 
} foo; 

Bạn sẽ có vấn đề cố gắng để khai báo một constructor. Điều này là tất nhiên bởi vì bạn đã không thực sự tuyên bố một struct có tên là "foo", bạn đã tạo một cấu trúc nặc danh và gán cho nó bí danh "foo". Điều này cũng có nghĩa là bạn sẽ không thể sử dụng "foo" với một nhà điều hành Phạm vi trong một file cpp:

foo.h:

typedef struct{ 
int x; 
void myFunc(int y); 
} foo; 

foo.cpp:

//<-- This will not work because the struct "foo" was never declared. 
void foo::myFunc(int y) 
{ 
    //do something... 
} 

Để khắc phục điều này, bạn phải làm điều này:

struct foo{ 
int x; 
foo(){}; 
}; 

hay này:

typedef struct foo{ 
int x; 
foo(){}; 
} foo; 

đâu sau này tạo ra một cấu trúc gọi là "foo" và cung cấp cho nó các bí danh "foo", do đó bạn không phải sử dụng từ khóa struct khi tham chiếu.

+0

về thời điểm: typedef struct foo { int x; foo (int x) {}; } foo; foo :: foo (int x) {...}; điều này không hoạt động ... – bordeo

20

Khi các câu trả lời khác đề cập đến, cấu trúc cơ bản được coi là một lớp trong C++. Điều này cho phép bạn có một hàm tạo có thể được sử dụng để khởi tạo cấu trúc với các giá trị mặc định. Bên dưới, hàm tạo có các đối số szb làm đối số và khởi tạo các biến khác thành một số giá trị mặc định.

struct blocknode 
{ 
    unsigned int bsize; 
    bool free; 
    unsigned char *bptr; 
    blocknode *next; 
    blocknode *prev; 

    blocknode(unsigned int sz, unsigned char *b, bool f = true, 
       blocknode *p = 0, blocknode *n = 0) : 
       bsize(sz), free(f), bptr(b), prev(p), next(n) {} 
}; 

Cách sử dụng:

unsigned char *bptr = new unsigned char[1024]; 
blocknode *fblock = new blocknode(1024, btpr); 
+1

Không chỉ "về cơ bản được coi là" ... từ khóa 'struct' nghĩa đen tạo ra một lớp. Giai đoạn. –

4

Trong C++ cả struct & class đều bình đẳng trừ struct's mặc định specifier truy cập thành viên là public & lớp có private.

Lý do có struct trong C++ là C++ là bộ siêu của C và phải tương thích ngược với legacy C types.

Ví dụ: nếu người dùng ngôn ngữ cố gắng bao gồm một số tệp tiêu đề C legacy-c.h trong mã C++ của mình &, chứa struct Test {int x,y};. Thành viên của struct Test nên có thể truy cập như như C.

9

Lưu ý rằng có một sự khác biệt thú vị (ít nhất là với MS C++):


Nếu bạn có một vani struct đơn giản như thế này

struct MyStruct { 
    int id; 
    double x; 
    double y; 
} MYSTRUCT; 

sau đó ở một nơi khác, bạn có thể khởi tạo một mảng của các đối tượng đó như thế này:

MYSTRUCT _pointList[] = { 
    { 1, 1.0, 1.0 }, 
    { 2, 1.0, 2.0 }, 
    { 3, 2.0, 1.0 } 
}; 

Tuy nhiên, ngay sau khi bạn thêm một constructor người dùng định nghĩa để mystruct như những thảo luận ở trên, bạn sẽ nhận được một lỗi như thế này:

'MyStruct' : Types with user defined constructors are not aggregate 
    <file and line> : error C2552: '_pointList' : non-aggregates cannot 
    be initialized with initializer list. 

Vì vậy, đó là ít nhất một sự khác biệt khác giữa một cấu trúc và một lớp. Kiểu khởi tạo này có thể không phải là thực hành OO tốt, nhưng nó xuất hiện khắp nơi trong mã WinSDK C++ kế thừa mà tôi hỗ trợ. Chỉ cần để bạn biết ...

+0

Điều này có vẻ như hành vi không chính xác từ trình biên dịch (giả sử phiên bản 'lớp' khai báo các thành viên của nó là' công khai'). MS nói ["Visual C++ không cho phép các kiểu dữ liệu trong một tổng hợp có chứa các nhà xây dựng"] (https://msdn.microsoft.com/en-us/library/0s6730bb.aspx), nhưng không chỉ ra lý do tại sao mà wouldn ' t áp dụng cho các lớp học là tốt. Và nó có vẻ làm việc trong VS 2015. – mgiuffrida

+0

hoạt động tốt với các bit mới nhất trong VS 2017 Preview 4 là tốt. API phiên bản 141 –

+0

Vì vậy, Aluan, bạn có nói rằng VS2017 bây giờ cho phép danh sách khởi tạo cho cấu trúc với các nhà xây dựng? Tôi chưa thử xem trước ... Cảm ơn! –

8

Trong C++ structC++ lớp chỉ có một sự khác biệt bởi các thành viên struct mặc định là công khai và các thành viên lớp là private.

/*Here, C++ program constructor in struct*/ 
#include <iostream> 
using namespace std; 

struct hello 
    { 
    public:  //by default also it is public 
     hello();  
     ~hello(); 
    }; 

hello::hello() 
    { 
    cout<<"calling constructor...!"<<endl; 
    } 

hello::~hello() 
    { 
    cout<<"calling destructor...!"<<endl; 
    } 

int main() 
{ 
hello obj;  //creating a hello obj, calling hello constructor and destructor 

return 0; 
} 
1

Cú pháp giống như lớp trong C++.Nếu bạn biết việc tạo ra hàm tạo trong C++ thì nó giống nhau trong cấu trúc.

struct Date 
{ 
int day; 

Date(int d) 
{ 
    day = d; 
} 
void printDay() 
{ 
    cout << "day " << day << endl; 
} 

}; 

Cấu trúc có thể có mọi thứ như là lớp trong C++. Như đã nói trước sự khác biệt chỉ là mặc định thành viên C++ có quyền truy cập riêng nhưng trong cấu trúc nó là public.But theo xem xét lập trình Sử dụng từ khóa struct cho cấu trúc dữ liệu chỉ. Sử dụng từ khóa lớp cho các đối tượng có cả dữ liệu và hàm.