2010-10-06 38 views
6

Giả sử tôi có một lớp có tên là Base và một lớp có nguồn gốc từ nó được gọi là SuperBase. Cho rằng add mất trong một Base*, một trong những sẽ là hợp lệ:Truyền tới mức độ hợp lệ của lớp cơ sở

SuperBase *super = new SuperBase; 
bases.add(super); 

Hoặc

SuperBase *super = new SuperBase; 
bases.add((Base*)super); 
+0

Tôi không thể nghĩ ra một tiêu đề hay cho câu hỏi, nhưng tôi nghĩ điều này tốt hơn. – GManNickG

Trả lời

9

Các công trình đầu tiên càng lâu càng SuperBase công khai xuất phát từ Base, thông qua một chuyển đổi ngầm từ nguồn gốc đến -base:

struct base { virtual ~base() {} }; 
struct derived : base {}; 

base* b = new derived; // okay 

Công trình thứ hai là tốt, nhưng bỏ qua bảo vệ Base:

struct derived : private base {}; // private base 

base* b = new derived; // not okay, base is private 
base* b = (base*)(new derived); // okay, but gross 

Nếu đó là private, có thể bạn không nên truyền đến nó.

+1

+1 đối với hành vi không xác định – jmasterx

+0

sử dụng 'static_cast ' thay vì tập lệnh kiểu C (Base *) 'để đảm bảo bạn không xử lý hành vi không xác định. –

+2

Nhưng điều đó không đúng! (Ít nhất là trong C++ 03). C-phong cách đúc đến một cơ sở không thể tiếp cận * là * đảm bảo để làm việc một cách chính xác (tức là nếu cơ sở có thể truy cập). Con trỏ kết quả là một con trỏ hợp lệ cho đối tượng con cấp cơ sở của kiểu 'Base' và nó có thể được sử dụng một cách an toàn như vậy. I E. C-style cast không phải là 'reinterpret_cast' trong trường hợp này, mà là' static_cast' bỏ qua sự bảo vệ. Đó là, tất nhiên, vẫn còn là một thực hành lập trình xấu, vì nó bỏ qua bảo vệ, nhưng nó "hoạt động". Tại sao bạn nói hành vi này là không xác định? – AnT

1

Cả hai đều hợp lệ - một đứa trẻ có thể được sử dụng ở nơi có tham chiếu/trỏ đến cha mẹ. Điều này được gọi là đa hình.

1

Cả hai đều hợp lệ, mặc dù nhập loại super đến Base* là không cần thiết.

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