C++;:跟踪类对象 我定义了C++类,并且在我的程序运行时创建了该类的许多对象。
我需要一个C++;:跟踪类对象 我定义了C++类,并且在我的程序运行时创建了该类的许多对象。,c++,oop,C++,Oop,我需要一个get\u object\u by\u name方法 这就是我在python中要做的: class Person(): all_instances = [] def __init__(self, name, age): self.name = name self.age = age self.all_instances.append(self) @classmethod def get_obj_by_na
get\u object\u by\u name
方法
这就是我在python中要做的:
class Person():
all_instances = []
def __init__(self, name, age):
self.name = name
self.age = age
self.all_instances.append(self)
@classmethod
def get_obj_by_name(cls, name):
for obj in cls.all_instances:
if obj.name == name:
return obj
我如何在C++中实现?
< P> C++没有Python中的代码< > ALLUBLUTION<代码>的特性。 你必须自己处理这件事 首先,您需要将类的不同对象存储在一个容器中(例如,std::list persons
)
get\u object\u by\u name
如下所示
Person & get_object_by_name(const std::string &name) {
for (auto & person : persons) {
if (person.get_name() == name) {
return person;
}
}
}
Person
需要有一个方法get\u name()
。或者,您可以重载操作符==
get\u object\u by\u name
需要访问Person
。因此最好将它们放入类中
class Persons{
public:
Person & get_object_by_name(const std::string &name);
// constructor to fill persons
// method to fill persons
private:
std::list<Person> persons;
};
班级人员{
公众:
Person&get\u object\u by\u name(const std::string&name);
//建造师负责填充人员
//填补空缺的方法
私人:
std:列出人员;
};
正如SPD所指出的,容器的选择并非无足轻重。如果您使用and
std::vector
,它会随着时间的推移而增长,这将导致重新分配,因此所有返回的引用都将无效。您可以使用无序映射(哈希映射,需要C++11)或映射(rbtree)来模拟Python的字典
类对象{
public://为了简单起见,您将需要使用ctor、getter和setter。
std::字符串名;
//其他领域。。。
};
std::无序的_映射对象;
对象*通过名称获取对象(const std::string&name){
自动映射迭代器=objects.find(name);
返回map\u iterator==objects.end()?nullptr:map\u iterator->second;
}
请记住,在C++中没有自动内存管理功能,因此您需要将对象存储在某个位置,以防止内存泄漏或指针悬空。如果您希望对象拥有对象,请将原始指针替换为唯一的\u ptr(或共享的\u ptr,具体取决于用例):
std::无序映射对象;
>P>正如其他答案中所提到的,C++中不存在这种特性,必须自己编写代码。您已经有了一些例子,说明如何通过定义外部存储类和自己跟踪对象来实现它。下面是另一种将对象跟踪的责任委托给<代码>的方法。关于
类本身。其他假设:
- 您只能使用参数化构造函数(或删除
explicit
关键字以使其转换构造函数)
- 人名必须是唯一的
- 您要小心,不要试图对堆栈上分配的对象调用
delete
用ValGrn.VC++验证的例子:你可以在<代码> STD中记录::MAP< <代码>静态STD::vector < /COD>成员变量。Python中的类变量在C++中是等价的,作为<代码>静态< /代码>成员,但你确实想这样做吗?听起来像是一个糟糕的设计,应该用另外的方式解决。(但不是真的重复)回答。@Sky它违反了单一责任规则-你的类做了它设计用来做的事情,并且它存储了自己的实例。而且这种实现背后的用例通常也有一种不好的味道。我不是说它一定不好(缺少这方面的信息),但值得仔细检查。
class Person
{
public:
/* for example simplifity I delete all the other CTors */
Person() = delete;
Person(const Person& other) = delete;
Person(Person&& other) = delete;
explicit Person(const std::string& name): name_(name)
{
std::cout << "Person(" << name_ << ");" << std::endl;
if (all_instances_.count(name_) != 0)
{
std::cout << "Person with name " << name_ << " already exists" << std::endl;
throw std::runtime_error("Person with that name already exists");
}
all_instances_.emplace(std::make_pair(name_, this));
}
~Person()
{
std::cout << "~Person(" << name_ << ");" << std::endl;
all_instances_.erase(name_);
}
static Person* get_person_by_name(const std::string& name)
{
if (all_instances_.count(name) == 0)
{
std::cout << "Person with name " << name << " does not exist" << std::endl;
return nullptr;
}
return all_instances_.find(name)->second;
}
private:
static std::map<std::string, Person*> all_instances_;
std::string name_;
};
std::map<std::string, Person*> Person::all_instances_;
int main(int argc, char* argv[])
{
Person p1("person1");
try
{
Person p2("person1"); // exception
}
catch (const std::exception& e)
{
std::cout << "Exception: " << e.what() << std::endl;
}
{
Person p3("person3");
Person* p4 = new Person("person4");
new Person("person5"); // lost pointer, but later we get it from the map
delete p4;
// p3 out of scope
}
auto person5 = Person::get_person_by_name("person5");
delete person5;
auto person1 = Person::get_person_by_name("person1");
if (person1) std::cout << "Person1 still exists" << std::endl;
auto person3 = Person::get_person_by_name("person3");
if (!person3) std::cout << "Person3 does not exist anymore" << std::endl;
return 0;
// p1 out of scope
}
Person(person1);
Person(person1);
Person with name person1 already exists
Exception: Person with that name already exists
Person(person3);
Person(person4);
Person(person5);
~Person(person4);
~Person(person3);
~Person(person5);
Person1 still exists
Person with name person3 does not exist
Person3 does not exist anymore
~Person(person1);