2009-12-18 83 views

Trả lời

4

Số đối tượng để làm gì? Nếu bạn muốn đếm số đối tượng của một lớp cụ thể, bạn có thể sử dụng bộ đếm tĩnh. Một cái gì đó như dưới đây .. Tăng truy cập vào sáng tạo và sụt lần trong khi phá hủy ..

class A 
{ 
    public: 
    static int counter; 
    A() 
    { 
     counter ++; 
    } 
    virtual ~A() 
    { 
     counter --; 
    } 
}; 

int A :: counter = 0; 
+0

Làm thế nào để bạn theo dõi nếu đối tượng được tạo bằng cách sử dụng malloc? –

+0

@KranthiKumar Nó * không * được tạo bởi 'malloc()'. ' Nó được phân bổ * tĩnh, hoặc bằng 'mới', hoặc trên ngăn xếp; nó được * xây dựng * bởi một trong các nhà xây dựng của nó; và nó bị phá hủy bởi destructor của nó. – EJP

0

Bạn có thể tạo một biến truy cập vào công chúng: các lớp học của bạn (giả sử ở đây bạn đang nói về đếm các đối tượng từ một lớp học mà bạn đã tạo)

class Widget { 
public: 
    Widget() { ++count; } 
    Widget(const Widget&) { ++count; } 
    ~Widget() { --count; } 

    static size_t howMany() 
    { return count; } 

private: 
    static size_t count; 
}; 
// obligatory definition of count. This 
// goes in an implementation file 
size_t Widget::count = 0; 

Taken từ ddj.com

+0

bạn nên đọc toàn bộ bài viết từ motters scott để thấy rằng giải pháp này không phải là tốt nhất. Ở cuối bài viết, ông mô tả cách tiếp cận mẫu được đề cập trong các bài viết khác. –

27

Tạo lớp mẫu với một bộ đếm tĩnh.

Mỗi đối tượng trong ứng dụng của bạn sau đó sẽ mở rộng lớp mẫu này.

Khi hàm tạo được gọi là số tĩnh tăng (biến tĩnh là mỗi lớp - được chia sẻ bởi tất cả các đối tượng của lớp đó).

Ví dụ thấy Object Counter sử dụng Curiously recurring template pattern:

template <typename T> 
struct counter 
{ 
    counter() 
    { 
     objects_created++; 
     objects_alive++; 
    } 

    virtual ~counter() 
    { 
     --objects_alive; 
    } 
    static int objects_created; 
    static int objects_alive; 
}; 
template <typename T> int counter<T>::objects_created(0); 
template <typename T> int counter<T>::objects_alive(0); 

class X : counter<X> 
{ 
    // ... 
}; 

class Y : counter<Y> 
{ 
    // ... 
}; 

Cách sử dụng cho đầy đủ:

int main() 
{ 
    X x1; 

    { 
     X x2; 
     X x3; 
     X x4; 
     X x5; 
     Y y1; 
     Y y2; 
    } // objects gone 

    Y y3; 

    cout << "created: " 
     << " X:" << counter<X>::object_created 
     << " Y:" << counter<Y>::object_created 
     << endl; 

    cout << "alive: " 
     << " X:" << counter<X>::object_alive 
     << " Y:" << counter<Y>::object_alive 
     << endl; 
} 

Output:

created: X:5 Y:3 
alive: X:1 Y:1 
+0

Xin chào. Cách tiếp cận tốt đẹp. Tôi không bao giờ biết về điều đó. Cảm ơn! – bdhar

+0

Một số thời gian trước đây tôi đã làm một số đa hình tĩnh và va vào ví dụ này, tôi thực sự thích nó, và đa hình tĩnh là mát mẻ ... – stefanB

+0

Giải pháp tốt đẹp, tôi có một nghi ngờ mặc dù .. là nó thực sự cần thiết để làm cho destructor ảo trong mẫu lớp khi sử dụng CRTP? Tôi chỉ lo lắng về chi phí kích thước nhỏ gây ra bởi các bảng v .. – Naveen

10
template <class T> 
class Counter 
{ 
    private: 
     static int count; 
    public: 
    Counter() 
    { 
     count++; 
    } 
    Counter(const Counter &c) 
    { 
     count++; 
    } 
    ~Counter() 
    { 
     count--; 
    }  
    static int GetCount() { 

     return count; 
    } 
} 

template<class T> 
int Counter<T>::count = 0; 



class MyClass : private Counter<MyClass> 
{ 
    public: 
     using Counter<MyClass>::GetCount; 
} 

Kỹ thuật này được gọi là CRTP

+3

@stefanB, Đây là cách tiếp cận chính xác. Bạn cần phải có bản sao constructor trong Counter. – Jagannath

+1

+1, cách tiếp cận của stefanB không xử lý 'X x2; X x3 = x2; '. Nhưng bạn không thể khởi tạo đếm như vậy, vì nó không phải là const. – KeatsPeeks

+0

ya u r đúng ... i hv để xác định nó đã loại bỏ lớp. – Ashish

3

Bạn phải quá tải các toán tử mới và xóa để tính phân bổ bộ nhớ.

void * operator new (size_t size) 
{ 
    void * p = malloc (size); 
    num_allocations++; 
    return p; 
} 

void operator delete (void * p) 
{ 
    num_deletions++; 
    free (p); 
} 
+0

Tôi nghĩ rằng [] mới và xóa [] cũng phải bị quá tải nếu bạn muốn theo dõi các đối tượng trên heap. – Ashish

+0

Có bạn là đúng Mac. Tôi chỉ cố bắt anh ấy bắt đầu. Bạn cần phải quá tải mọi biến thể mới mà bạn đang sử dụng. – DevDevDev

+0

không vi phạm mã? xóa nên gọi destructor đầu tiên; – NoSenseEtAl

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