2009-04-17 38 views
12

1) quy ước sử dụng trong thực tế là gì khi typedef'ingQuy ước đặt tên khi bản đồ STL phức tạp typdef là gì?

cái gì đó như

typedef std::map<SomeClass*, SomeOtherClass> [SomeStandardName>] 
typedef std::map<SomeClass*, std<SomeOtherClass> > <[SomeStandardName] 

2) Nơi nào bạn thường đặt typedef: tập tin tiêu đề toàn cầu, địa phương để các lớp học?

3) Bạn đã nhập lặp đi lặp lại hoặc bản đồ const <> phiên bản?

4) Giả sử bạn có bản đồ được sử dụng bởi hai khái niệm khác nhau, bạn có tạo hai typedef riêng biệt không?

typedef map<string, SomeClass *> IDToSomeClassMap; 
typedef map<string, SomeClass *> DescriptionToSomeClassMap; 

Cảm ơn


Chỉnh sửa # 1

Tôi quan tâm đặc biệt trong typedef bản đồ STL, như

typedef map<int, string> IdToDescriptionMap 

hoặc

typedef map<int, string> IdToDescription 

Thực tiễn phổ biến là gì?

Trả lời

12

tôi thích quy ước sau:

typedef std::map< Foo, Bar > FooToBarMap 

tôi cố tình tránh typedef'ing các vòng lặp, tôi thích một cách rõ ràng đề cập đến chúng như:

FooToBarMap::const_iterator 

Kể từ khi vòng lặp đã là một de facto tên tệp chuẩn. Và FooToBarMapConstIter thực sự là ít rõ ràng hơn để đọc khi lướt mã, tôi tìm thấy.

0

Tôi không biết nếu có bất kỳ quy tắc chính thức nào về chủ đề này nhưng tôi thường thêm loại lỗi ở vị trí phù hợp nhất với việc sử dụng trong dự án.

  • Nếu typedef chỉ được sử dụng trong vòng một lớp sau đó thêm các typedef bên trong định nghĩa lớp
  • Nếu typedef được sử dụng bởi một số lớp học không liên quan thêm nó vào một tập tin tiêu đề ở một mức độ phạm vi không gian tên

Đối với tên thực tế của loại đã gõ. Tôi đặt tên nó bất cứ điều gì có ý nghĩa cho typedef. Tôi không cung cấp cho typedef tên bất kỳ quy ước đặc biệt nào như tiền tố với _t hoặc bất kỳ thứ gì dọc theo các dòng đó. Ví dụ

typedef stl::map<stl::string,Student> NameToStudentMap; 
0

Không, chỉ cần ghi nhớ các quy tắc chung để đặt tên định danh (không _ để bắt đầu với vv). Ngoài ra, nếu tổ chức của bạn có hướng dẫn mã hóa, tốt nhất là nên tuân theo nó.

Thông thường, khi xác định lớp mẫu của riêng bạn, nó trở nên lộn xộn mà không có typedefs - vì vậy tôi sẽ tạo chúng ở đó dưới dạng phím tắt tiện dụng. Tuy nhiên, nếu nó thực sự là một loạt các lớp học, tôi muốn có nó ở mức namespace.

+0

Tôi quan tâm đặc biệt trong các bản đồ STL typedef, chẳng hạn như typedef map IdToDescriptionMap hoặc typedef đồ IdToDescription những thực tế phổ biến là gì? –

+0

Tôi đã đề cập đến những gì chúng tôi làm nói chung - không có quy tắc đặc biệt cho bản đồ. FWIW, chúng ta có thể gọi một bản đồ a Dict nếu nó phù hợp với môi trường đối tượng. – dirkgently

+0

+1 ........... kiếm được !!! –

0

Chúng tôi sử dụng sau tại nơi làm việc của tôi:

 
typedef std::map WhateverMap; 
typedef WhateverMap::iterator WhateverIter; 
typedef WhateverMap::const_iterator WhateverCIter; 

Theo như vị trí đi, mà thay đổi. Nếu đó là lớp cụ thể, nó có thể là trong một cấu trúc Impl, hoặc có thể nằm trong khu vực được bảo vệ hoặc riêng tư của khai báo lớp. Nếu nó tổng quát hơn (được sử dụng trên các tệp, được sử dụng trong một API), chúng tôi đặt nó trong một tiêu đề kiểu "FooTypes.h" riêng biệt.

Lưu ý rằng vì đôi khi chúng ta thường thay đổi kiểu cơ bản, chúng ta có thể sử dụng "WhateverCollection" thay vì "WhateverVec" hoặc "WhateverList".Nó không phải là không phổ biến để có một "WhateverList" thực sự được gõ vào một vector hoặc một slist, tùy thuộc vào dấu chân mong muốn và đặc tính hiệu suất.

2

Không có quy tắc chung được thống nhất về các tên này. Những gì tôi thường làm là sử dụng tên của lớp "giá trị" được gắn liền với Bản đồ. Trong ví dụ của bạn sẽ là SomeOtherClassMap. Tôi sử dụng quy ước này vì điều thú vị hơn là bản đồ của bạn chứa các đối tượng "giá trị" loại SomeOtherClass sau đó bạn tìm kiếm chúng bằng "phím" của SomeClass.

0

Lãi câu hỏi:
tôi nhìn vào tăng, và tôi thấy họ không có bất kỳ quy tắc toàn cầu, nhưng ước sử dụng nhiều nhất

typedef std::map< key, value > some_domain_specific_name_map; 

hoặc

typedef std::map< key, value > some_domain_specific_name_map_type; 

cũng thực hành tốt để làm cho typedef cho value_type hoặc iterators, thường chúng có cùng tên với bản đồ nhưng với kết thúc _value_type, _iterator.

0

Thông thường tôi định nghĩa tên liên quan thành typedef cho biết loại đối tượng.

Ex:

typedef std::vector<ClassCompStudent*> StudentCollection; 

typedef std::map<std::string /*id*/, ClassCompStudent* /*pStudent*/> IDToStudentMap; 

Ngoài ra, tôi xác định chúng như nào trong phần đầu lớp, trong đó đối tượng đã được tạo. Điều đó mang lại cho tôi lợi ích của việc thay đổi loại vùng chứa mà không vi phạm mã máy khách.

class Test 
{ 
public: 
    typedef std::vector<ClassCompStudent*> StudentCollection; 

    /* Users of Test need not know whether I use vector or list for 
     storing students. They get student collection and use it*/ 
    bool getStudents(StudentCollection& studentList) const; 

    void print() 
    { 
     //do printing 
    } 
private: 

    StudentCollection m_StudentList; 
}; 

bool function(const Test& testObj) 
{ 
    //If StudentCollection gets changed to list, this code need not be changed. 
    StudentCollection aCollection; 
    testObj.getStudents(aCollection); 
    std::for_each(aCollection.begin(), aCollection.end(), std::mem_fun(&Test::print)); 
} 
0

Sử dụng từ "Bản đồ" hoặc "Vector" dưới dạng ký hiệu vô dụng. Đây là những từ được kết nối với việc thực hiện và không liên quan đến mô hình kinh doanh.

Bạn không phải chứng minh rằng loại này là vectơ hoặc bản đồ. Bạn có thể sử dụng Danh sách. Giống như

typedef std::vector<std::string> List; 
typedef std::set<std::string> List; 

Cả hai đều là danh sách chuỗi. Và điều này là đúng.

typedef std::map<std::string, Object> List; 
or 
typedef std::map<std::string, Object> NamedList; 

Điểm của tôi không sử dụng ký hiệu hungarian.

1

Phần thứ hai của câu hỏi là câu hỏi thú vị nhất đối với tôi. Tôi thích đặt typedef s trong các lớp sử dụng chúng, khi có vị trí hợp lý cho chúng, ngay cả khi chúng được sử dụng trong các lớp khác. Nhưng điều đó gây ra một số vấn đề với các khai báo chuyển tiếp (mà chúng tôi sử dụng rất nhiều cho tốc độ biên dịch).Ví dụ, trong một dự án gần đây, chúng tôi đã có một lớp được gọi là Io, với typedef được nhúng có tên là Point, được tạo cho mã rất dễ đọc - Io::Point rất rõ ràng và dễ đọc. Nhưng bất cứ khi nào chúng tôi muốn sử dụng loại này, chúng tôi phải đưa vào khai báo lớp Io, ngay cả khi tất cả những gì chúng tôi cần là tuyên bố của Io::Point, vì không có cách nào (mà tôi biết) lớp được khai báo chuyển tiếp.

Trong trường hợp đó, chúng tôi đã thực hiện cả hai cách. Chúng tôi đã tạo loại IoPoint toàn cầu và sau đó typedef d Io::Point vào nó (để mã đã viết của chúng tôi không bị sửa đổi). Không phải là câu trả lời đẹp nhất, nhưng nó đã hoàn thành công việc.

Đối với các phần khác:

Chúng tôi không sử dụng bất kỳ quy ước đặc biệt nào cho tên. Đối với bản đồ, chúng tôi thường sử dụng * DescriptiveSomething *** Map ** (vì có khả năng chúng tôi sẽ không bao giờ thay đổi từ bản đồ sang một số loại vùng chứa khác), nhưng nếu DescriptiveSomething đủ mô tả và không xung đột với hiện tại tên, chúng ta thường sử dụng nó thay thế.

Chúng tôi thường không bận tâm việc tạo typedef cho các trình vòng lặp vì dễ dàng (và rất dễ đọc) để sử dụng đơn giản Type::iterator hoặc Type::const_iterator. Điều đó nói rằng, chúng tôi làm đôi khi đã nhập chúng nếu tên loại quá dài mà Type::const_iterator làm cho mã trông quá "chunky". (Không biết cách nào tốt hơn để nói, nhưng bạn có thể biết ý tôi là gì.)

Chúng tôi tạo các kiểu chữ khác nhau cho mỗi khái niệm, ngay cả khi hai trong số chúng xác định chính xác cùng một loại. Họ có thể thay đổi độc lập với nhau, do đó, có tên loại khác nhau cho họ đơn giản hóa bất kỳ tái cấu trúc sau này. Nó cũng làm cho mã dễ đọc hơn, trong nhiều trường hợp.

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