2012-02-29 28 views
8

EDIT: Đây là một cuộc thảo luận về thực hành tốt nhất trong trường hợp (được đơn giản hóa) được trình bày bên dưới. Dù công cụ, kiểu mã hóa hay cái gì khác bạn muốn đề xuất, hãy đăng nó lên. Cảm ơn.Có cách nào đặc biệt để khai báo/định nghĩa các hàm tạo C++ (và hàm hủy)

Tại sao không có cách nào đặc biệt để khai báo hoặc xác định ctors/dtors mà không nhân đôi tên của lớp? Nó gây phiền nhiễu, đặc biệt là khi tạo mẫu và kết thúc thay đổi tên của lớp rất nhiều.

Những gì tôi có nghĩa là một cái gì đó với typedef như thế này:

struct SomeClassThatDoesSomething { 
    typedef SomeClassThatDoesSomething ThisClass; 
    ThisClass() { PrepareToDie(); } 
    ThisClass(int a) : _a(a) { PrepareToDie(); } 
    ThisClass(float a, int b) : _b(a), _a(b) { PrepareToDie(); } 
    ThisClass(float a, char * b) : _b(a), _c(b) { PrepareToDie(); } 
    ThisClass(char * a, int b) : _c(a), _a(b) { PrepareToDie(); } 
    ThisClass(ThisClass &rhs) { } 
    ~ThisClass() {} 
    void Burn() {} 
    void PrepareToDie() {} 
    int _a; 
    float _b; 
    char *_c; 
}; 

struct SomeDerivedClassThatDoesSomething : public SomeClassThatDoesSomething { 
    typedef ThisClass BaseClass; 
    typedef SomeDerivedClassThatDoesSomething ThisClass; 
    ThisClass(BaseClass &is_not_amused) : BaseClass(is_not_amused) { BaseClass::_a = 1; PrepareToDie(); } 
    ThisClass(float a, char * b) : BaseClass(b, a) {} 
    ~ThisClass() { BaseClass::Burn(); } 
    unsigned int _a; // Different semantics up the tree. 
}; 

//EDIT: Consider this: Enforce export name decoration policy. 
#define DLL_API __declspec(dllexport) 
// ... or dllimport - not the point here 
#define def_export_struct(name) struct C##name; typedef C##name *P##name; struct DLL_API C##name 

def_export_struct(SomeOtherClassThatDoesSomething) : public SomeDerivedClassThatDoesSomething 
{ 
//... 
}; 
namespace mass_destruction { 
    def_export_struct(Int) 
    { 
    //... (The point is that search and replace gets very unreliable in big projects) 
    } 
}; 

Nó chỉ hoạt động cho ctors và chỉ trên MSVC; Tôi đã sử dụng nó và, mặc dù không phải là một tính năng lớn, nó làm cho cuộc sống dễ dàng hơn. Đây là một ví dụ tầm thường, nhưng hãy tưởng tượng một cấu trúc khá phức tạp. (Một hiệu ứng phụ tiện dụng cũng là bạn có một bí danh trong lớp mà không cần phải theo dõi tên của nó.) Tôi có thiếu gì đó không? Tôi thực sự là người duy nhất cần điều này? Vấn đề không phải là liệu nó có biên dịch hay không, quan điểm là tôi đã làm việc đó một phần khắp nơi cho tôi và điều đó thật kỳ diệu. Cho đến khi tôi đạt tiêu chuẩn ... (Đây không phải là một cuộc thảo luận tuân thủ.)

+4

IDE hiện đại có khả năng tái cấu trúc tốt (hoặc có plugin cung cấp cho chúng), vì vậy việc đổi tên lớp sẽ trở nên rất đơn giản. Do đó, tôi thấy không cần thiết cho một tính năng như vậy. –

+1

Nó không thực sự rõ ràng những gì bạn đang yêu cầu. Cho dù một tính năng như vậy tồn tại, hay * tại sao * nó không tồn tại, cái gì khác? Và bằng cách nói rằng bạn đã biết về một tính năng như vậy và bạn không quan tâm đến việc tuân thủ, thật khó để biết bạn muốn gì hơn. – jalf

+4

@ BjörnPollex: tái cấu trúc capabilites cho C++ thường tụt hậu xa phía sau Java/C# đối tác của họ. Và điều đó sang một bên, không phải ai cũng sử dụng IDE, và nó hầu như không phải là mục đích của IDE để cải tiến ngôn ngữ * không cần thiết * – jalf

Trả lời

6

Bao giờ nghe nói về tìm kiếm và thay thế?

Tôi đoán hầu hết mọi người đều sử dụng ex, vim, sed. vv: s/search/replace/g hoặc tương đương với thay đổi tên của các lớp học của họ, hoặc không thay đổi chúng thường xuyên bị khó chịu do thiếu tính năng này.

Bạn có thể sử dụng một #define để làm điều này compliantly:

#define THIS_CLASS MyLongClassNameThatIChangeLotsAndLots 
class THIS_CLASS{ 
    THIS_CLASS() { PrepareToDie(); } 
    THIS_CLASS(int a) : _a(a) { PrepareToDie(); } 
    THIS_CLASS(float a, int b) : _b(a), _a(b) { PrepareToDie(); } 
    THIS_CLASS(float a, char * b) : _b(a), _c(b) { PrepareToDie(); } 
    THIS_CLASS(char * a, int b) : _c(a), _a(b) { PrepareToDie(); } 
    THIS_CLASS(THIS_CLASS &rhs) { } 
    ~THIS_CLASS() {} 
}; 
#undef THIS_CLASS 

là gì xáo trộn, tôi sẽ đồng ý, là thiếu một cách tiêu chuẩn để tham khảo các lớp cơ sở (es) của một loại - - Tôi thường ở chế độ riêng tư typedef ... base_t trong các lớp học, sau đó sử dụng cho các danh sách khởi tạo, v.v.

+1

preparetoDie() ... +1 – UmNyobe

+0

Tôi cũng sử dụng sed, nhưng nó không có sẵn trong một số hệ thống. Macro của bạn không giúp được nhiều bởi vì các lớp có thể có các hàm tạo riêng biệt. Bạn không thể giả sử ngay cả một bộ tối thiểu của ctors phổ biến. Cá nhân tôi nghĩ nó không xứng đáng với thời gian. – jweyrich

+0

Một vấn đề khác là xác định lại macro trở nên xấu xí với #pragma push_macro ("THIS_CLASS") và #pragma pop_macro ("THIS_CLASS"). Doable, nhưng khó theo dõi hơn. Tôi sẽ tiết kiệm một điều như vậy cho ít hơn các định nghĩa phổ biến. – ActiveTrayPrntrTagDataStrDrvr

3

Nếu tên lớp của bạn bị bẻ cong dài, xem xét sử dụng nhiều hơn namespace.

namespace, kết hợp với using là rất tốt cho việc typenames của bạn chỉ như là tiết vì mỗi nhu cầu bối cảnh.

namespace Something 
{ 
    struct Derived : public SomeClass 
    { 
    Derived() {...etc.} 

    } 
} 
+0

Các tên dài là trên đầu mục đích. Nhưng quay lại câu trả lời của bạn: Điều này có thực sự khiến việc tìm kiếm và thay thế khó hơn không? Nó sẽ giới thiệu nhiều tên trùng lặp. – ActiveTrayPrntrTagDataStrDrvr

+0

@ user1240436: Nó làm cho s/r khó hơn, vâng. Câu trả lời của tôi không thực sự áp dụng sau khi bạn chỉnh sửa. –

+0

Nó vẫn hữu ích như một cách để lên kế hoạch cho một dự án nhỏ hơn. – ActiveTrayPrntrTagDataStrDrvr

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