在C++中获取类的所有对象

its*_*hre 1 c++ class object

有没有办法可以在C++中获取类的所有对象.就像在Python中一样,我们可以做到

class_name.objects.all() 
Run Code Online (Sandbox Code Playgroud)

得到一个类的所有对象.如果它存在,它在C++中的模拟是什么?

mad*_*tya 8

你可以自己做,但要确保你知道你在做什么.

怎么样:

C++中没有任何东西可以做到这一点,但是你自己很容易做到这一点.关键是要认识到一个类可以有静态成员变量和函数(即属于整个类的函数,而不是类的单个对象).

因此,您可以使用某种表或其他数据结构来存储对每个对象的引用.像这样:

class A {

public:
  //constructor assigns this object an id based on the static value curID,
  //which is common to the class (i.e. the next class to call the constructor 
  //will be assigned an id thats 1 more than this one
  //also, constructor adds the pointer to this object to a static map of ids 
  //to objects. This way, the map can be queried for the pointer to an object 
  //that has a particular id
  A() { 
    id = curID++;
    objects[id] = this;
  }

  //copy constructor ensures an object copied from another does not 
  //take the id of the other object, and gets added to the map
  A(const A&) {
    id = curID++; //don't want have the same ID as the object we are copying from
    objects[id] = this;
    x = A.x;
    y = A.y;
  }

  A&  operator=(const A&) {
    id = curID++;
    objects[id] = this;
    x = A.x;
    y = A.y;
    return *this; 
  }

  //destructor removes the pointer to this object from the map
  ~A() {
    objects.erase(id);
  }

  //function to get the map that stores all the objects
  static map<int, A*>& GetMapOfObjects() { 
    return objects;
  }

private:
  //the following variable is **static**, which means it does not
  //belong to a single object but to the whole class. Here, it is
  //used to generate a unique ID for every new object that's 
  //instantiated. If you have a lot of objects (e.g. more than
  //32,767), consider using a long int
  static int curID;  

  //this variable is also static, and is map that stores a pointer
  //to each object. This way, you can access the pointer to a
  //particular object using its ID. Depending on what you need, you
  //could use other structures than a map
  static map<int, A*> objects; 


  //this is a (non-static) member variable, i.e. unique to each object.
  //Its value is determined in the constructor, making use of curID.
  int id;

  //these are some other member variables, depending on what your object actually is
  double x;
  double y; 
}
Run Code Online (Sandbox Code Playgroud)

注意:上面的设计非常基础而且不完整,但只是为了让您了解如何实现您使用静态成员/函数所要求的内容.例如,对于要对所有对象执行的操作,例如,实现迭代元素映射的静态函数可能更好,而不是获取映射然后在"外部"执行迭代.

为什么:

我自己从未使用过这种方法,但我能想到的一个潜在用例是例如在图形或游戏应用程序中,您可能只想绘制范围内的对象 并更改所有这些对象的绘制相关属性立刻,例如颜色或大小.我正在开发一个最终可能需要这样的应用程序(一种可视化调试器).我相信人们可以在评论中提供更多的例子.

为什么不:

涉及继承时,图片变得复杂.

  • 如果你有一个派生自A的B级(即B"是"A"),那么谁应该跟踪B的对象?A中对象的静态成员,或B中的类似对象,或两者兼而有之?
  • 让我们两个说.那么,如果应用于A中所有对象的静态函数调用每个对象上的虚拟成员函数,会发生什么?如果已在派生类中重写虚函数,则将调用该函数,而不是在A类中跟踪的所有实际为B对象的对象.如果你再在B中的另一个静态函数中再次调用该函数会发生什么?


Mad*_*nga 5

我不知道有什么办法,但您可以与static成员一起实施

#include <iostream>
#include <vector>
class MyClass{
private:
 static std::vector<MyClass*> objList;
public:
 MyClass() {
  objList.push_back(this);
 }
 static std::vector<MyClass*> getAllObjects(){
  return objList;
 }
};

std::vector<MyClass*> MyClass::objList;

main(){
 MyClass m,a;
 for (int i=0;i<MyClass::getAllObjects().size();i++){
  std::cout<<MyClass::getAllObjects()[i]<<std::endl;
 }
}
Run Code Online (Sandbox Code Playgroud)