2010-08-01 38 views
7

câu hỏi về C++ số lý do tại sao tối thiểu của các thành viên dữ liệu trong định nghĩa lớp là zeroTại sao các lớp C++ được phép có các thành viên dữ liệu bằng 0?

tôi nghĩ rằng nó phải là một, tức là con trỏ đến bảng ảo xác định bởi trình biên dịch

thanks a lot

+6

không phải tất cả các lớp đều có vtable, vì vậy điều đó không liên quan. – tenfour

+6

Cũng không làm vtables có bất cứ điều gì để làm với C + +. Họ chỉ là một kỹ thuật thực hiện phổ biến (và do đó không có gì để làm với ngôn ngữ) để thực hiện kế thừa (nhưng không phải là duy nhất). –

+4

Câu hỏi rõ ràng tôi sẽ hỏi là tại sao không cho phép các đối tượng có kích thước bằng không. Thực tế là nó là loại duy nhất có thông tin có thể được sử dụng. –

Trả lời

21

Nó thường là hữu ích khi có một lớp không có thành viên dữ liệu để sử dụng trong phân cấp thừa kế.

Lớp cơ sở chỉ có thể có một số typedef s được sử dụng trong nhiều lớp. Ví dụ: mẫu lớp std::iterator chỉ có các loại tiêu chuẩn được xác định để bạn không cần xác định chúng trong mỗi lớp trình vòng lặp.

Lớp giao diện thường không có thành viên dữ liệu, chỉ có chức năng thành viên ảo.

Một bảng ảo không liên quan gì đến các thành viên dữ liệu của một lớp.

+1

+1 để đề cập đến typedef. –

5

Vâng, trên thực tế C++ ủy quyền rằng tất cả các lớp phải chiếm một số không gian (Bạn cần để có thể tạo ra một con trỏ đến lớp đó). Họ chỉ cần một con trỏ đến một vtable mặc dù, nếu lớp là đa hình. Không có lý do gì cho một vtable ở tất cả trong một lớp monomorphic.

+0

@Billy tôi nghĩ rằng chỉ có một vtbl nếu bạn có chức năng ảo? – InsertNickHere

+1

@InsertNickHere: Đó là ý nghĩa của đa hình. –

+0

@Billy Dident biết rằng luôn luôn có một chức năng ảo kể từ im không được sử dụng để c + +. – InsertNickHere

5

Tôi đang làm việc trên thư viện đôi khi thậm chí sử dụng các loại - thở hổn hển! - thậm chí không phải là được xác định, ít có nhiều thành viên dữ liệu hơn!

Đó là, loại không đầy đủ, chẳng hạn như

struct foobar; 

này được sử dụng để tạo ra một cái tên rõ ràng, không có gì hơn.

Vì vậy, điều này hữu ích cho điều gì? Vâng, chúng ta sử dụng nó để tạo ra khác biệt thẻ, sử dụng bổ sung (trống rỗng, nhưng xác định đầy đủ) một loại:

template <typename TSpec> 
struct Tag { }; 

Bây giờ bạn có thể tạo thẻ riêng biệt như vậy:

struct TagForward_; 
typedef Tag<TagForward_> ForwardTag; 

struct TagRandomAccessible_; 
typedef Tag<TagRandomAccessible_> RandomAccessibleTag; 

Những lần lượt có thể được sử dụng để phân biệt các tình trạng quá tải chuyên biệt. Nhiều triển khai STL làm điều gì đó tương tự:

template <typename Iter> 
void sort(Iter begin, Iter end, RandomAccessibleTag const&) … 

Nói đúng ra, con đường gián tiếp thông qua một chung Tag lớp mẫu là không cần thiết, nhưng đó là một mẹo hữu ích vì lợi ích của tài liệu.

Tất cả điều này chỉ để cho thấy rằng một hệ thống loại (nghiêm ngặt, tĩnh) có thể được sử dụng theo nhiều cách khác nhau hơn là chỉ gói và đóng gói dữ liệu.

+2

những tên đó chỉ để minh họa cho ví dụ này? Tên có dấu gạch dưới hàng đầu theo sau là các ký tự viết hoa được dành riêng cho việc triển khai :) – jalf

+0

@jalf: tên chỉ để minh họa. Nhưng bạn nói đúng, đây, hãy để tôi thay đổi chúng. –

0

Việc sử dụng một lớp khác không có thành viên dữ liệu là để xử lý dữ liệu từ các nguồn khác. Mọi thứ được chuyển vào lớp khi chạy qua các con trỏ hoặc các tham chiếu và lớp hoạt động trên dữ liệu nhưng không lưu trữ dữ liệu nào.

Tôi đã không thực sự nghĩ về điều này cho đến khi tôi thấy nó được thực hiện trong một lớp UML tôi đã tham gia. Nó có sử dụng, nhưng nó thường tạo ra các lớp kết hợp.

0

Vì lớp học không phải là cấu trúc. Mục đích của họ, trái với niềm tin phổ biến, là không phải để giữ dữ liệu.

Ví dụ: hãy xem xét lớp cơ sở của trình xác thực xác định phương thức ảo chuyển một chuỗi để xác thực và trả về một bool.

Ví dụ về trình xác thực có thể từ chối các chuỗi có chữ in hoa trong đó. Đây là một ví dụ hoàn hảo về thời điểm bạn nên sử dụng một lớp, và theo định nghĩa của nó, rõ ràng không có lý do để có bất kỳ biến thành viên nào.

0

câu hỏi về C++ tại sao số lượng tối thiểu của các thành viên dữ liệu trong định nghĩa lớp là zero

Đó là zero bởi vì bạn có những trường hợp khác nhau của các lớp học nên không có các thành viên:

Bạn có thể thực hiện các lớp đặc điểm chỉ chứa các hàm tĩnh chẳng hạn. Các lớp này tương đương với một số namespace cũng có thể được nhận dạng dưới dạng một loại. Điều đó có nghĩa là bạn có thể khởi tạo một mẫu trên lớp và đảm bảo việc triển khai mẫu đó sử dụng các hàm trong lớp. Kích thước của một đặc điểm như vậy nên là 0.

Ví dụ:

class SingleThreadedArithmetic 
{ 
    static int Increment(int i) { return ++i; } 
    // other arithmetic operations implemented with no thread safety 
}; // no state and no virtual members -> sizeof(SingleThreadedArithmetic) == 0 

class MultiThreadedArithmetic 
{ 
    static int Increment(int i) { return InterlockedIncrement(i); } 
    // other arithmetic operations implemented with thread safety in mind 
}; // no state and no virtual members -> sizeof(MultiThreadedArithmetic) == 0 

template<class ThreadingModel> class SomeClass 
{ 
public: 
    void SomeFunction() 
    { 
     // some operations 
     ThreadingModel::Increment(i); 
     // some other operations 
    } 
}; 

typedef SomeClass<SingleThreadedArithmetic> SomeClassST; 
typedef SomeClass<MultithreadedArithmetic> SomeClassMT; 

Bạn có thể xác định loại lớp riêng biệt bằng cách thực hiện "tag" lớp: lớp học mà giữ không có giao diện hoặc dữ liệu, nhưng chỉ được sử dụng để phân biệt giữa riêng loại "logic" của các lớp dẫn xuất. Sự khác biệt có thể được sử dụng trong mã OOP bình thường hoặc trong mã templated. Các lớp "thẻ" này cũng có kích thước 0. Xem việc thực hiện thẻ trình vòng lặp trong thư viện STL hiện tại của bạn để biết ví dụ.

Tôi chắc chắn có những trường hợp khác mà bạn có thể sử dụng các lớp "không có kích thước".

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