2016-03-04 11 views
10

Đối với dự án cụ thể này, tôi không thể sử dụng các tính năng C++ 11 (ví dụ: decltype) vì trình biên dịch chưa hỗ trợ chúng. Tôi cần phải có khả năng cung cấp các lớp học hiện tại như một tham số mẫu, tốt nhất là trong vòng một macro mà không cần một cuộc tranh cãi (xem dưới đây), mà không mặc quần áo lên tờ khai class hoặc ẩn dấu ngoặc nhọn vvLàm cách nào để truy xuất loại lớp cơ sở trong C++?

class Foo: private Bar<Foo> { 
    MAGIC //expands to using Bar<Foo>::Baz; and some others 
    public: 
     void otherFunction(); 
     //... the rest of the class 
}; 

Lý tưởng nhất, tôi 'd như thế này hoạt động rất giống với macro Q_OBJECT của Qt, nhưng không giới thiệu một bước biên dịch trước và các lớp được tạo liên quan khác. typeid có thể hữu ích trong thời gian chạy, nhưng mục tiêu của tôi là hoàn thành tất cả điều này khi xây dựng.

Làm cách nào để viết macro MAGIC để tôi không cần lặp lại tên lớp mỗi lần?

+0

Câu hỏi này có vẻ là phiên bản C++ 03 của "[Tôi có thể triển khai kiểu tự trị' tự' trong C++ không?] (http://stackoverflow.com/q/21143835/ 560648) " –

+1

Tâm trí nếu tôi thay đổi tiêu đề thành * base clase *? * kèm theo lớp * làm cho nó có vẻ như bạn đang làm tổ và loại ra khỏi lớp bên ngoài. – NathanOliver

+0

Câu hỏi 'tự' trông rất giống nhau, nhưng nó không giống như bất kỳ giải pháp được đề xuất nào hoạt động trong C++ 03, như bạn đã lưu ý. Chắc chắn thay đổi tiêu đề nếu nó sẽ làm cho nó rõ ràng hơn. – multipleinterfaces

Trả lời

0

Bạn có thể sử dụng một "proxy" struct cho xây dựng lên các thừa kế (?):

template <typename S> 
struct Base : public S{ //always public, access is restricted by inheriting Base properly 
    using super = S; 
}; 

Cách sử dụng sẽ như sau:

#include <iostream> 

template <typename S> 
struct Base : public S { 
    using super = S; 
}; 

template <typename T> 
class Bar 
{ 
public: 
    virtual void f() { std::cout << "Bar" << std::endl; } 
}; 

class Foo : private Base<Bar<int>> 
{ 
public: 
    virtual void f() 
    { 
     std::cout << "Foo"; 
     super::f(); //Calls Bar<int>::f() 
    } 
}; 

class Fii : private Base<Foo> 
{ 
public: 
    virtual void f() 
    { 
     std::cout << "Fii"; 
     super::f(); //Calls Foo::f() 
    } 
}; 


int main() 
{ 
    Fii fii; 
    fii.f(); //Print "FiiFooBar" 
    return 0; 
} 
0

Tôi không nghĩ có bất kỳ ngôn ngữ cơ chế được hỗ trợ để trích xuất kiểu cơ sở từ một lớp. Bạn có thể sử dụng:

Lựa chọn 1

class Foo: private Bar<Foo> { 

#define BASE_TYPE Bar<Foo> 
    // Use BASE_TYPE in MAGIC 
    MAGIC //expands to using Bar<Foo>::Baz; and some others 
#undef BASE_TYPE 

    public: 
     void otherFunction(); 
     //... the rest of the class 
}; 

Lựa chọn 2

class Foo: private Bar<Foo> { 

    typedef Bar<Foo> BASE_TYPE; 

    // Use BASE_TYPE in MAGIC 
    MAGIC //expands to using Bar<Foo>::Baz; and some others 

    public: 
     void otherFunction(); 
     //... the rest of the class 
}; 
+1

Bạn có thể tránh sự thừa bởi '#define 'ing' BASE_TYPE' _before_ khai báo lớp, vì vậy bạn có thể nói 'class Foo: private BASE_TYPE'. – mindriot

+3

Hoặc giữ nó trong lớp và sử dụng 'typedef' thay vì' # define' như 'typdef Bar BaseType;' –

+0

@RyanHaining, đó là lý do tại sao tôi có '# undef' ngay sau dòng' MAGIC'. –

1

gì về:

template<typename T> 
class Base 
{ 
protected: 
    typedef Base<T> MagicBaseType; 
    namespace Baz { } 
}; 

class Derived1 : private Base<Derived1> 
{ 
    using MagicBaseType::Baz; 
} 


class Derived1 : private Base<Derived2> 
{ 
    using MagicBaseType::Baz; 
} 

hoặc, nếu bạn không thể sửa đổi cơ sở định nghĩa, sử dụng các mẫu và mu thừa kế ltiple

template<typename T> 
class Base 
{ 
protected: 
    namespace Baz { } 
}; 

template<typename T> 
class DerivedTemplate : public T 
{ 
protected: 
    typedef typename T BaseType; 
} 

class Derived : public Base<Derived>, public DerivedTemplate<Base<Derived>> 
{ 
using BaseType::Baz; 
} 
0

Nếu bạn thực sự không quan tâm về định dạng văn bản hoặc đau đầu bảo trì bạn có thể làm điều này mà không lặp lại những loại bằng cách vĩ mô lấy đối số kiểu:

#define MAGIC(BASE) \ 
BASE { \ 
    using BASE::baz; 

class Sub : private MAGIC(Base<Foo>) 

    public: 
    void otherFunction(); 
}; 

nhưng điều này làm cho tôi cảm thấy khá xấu về bản thân mình

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