如何在C++中定义一个类的图(字段类型,获取器和设置器)

huangapple go评论84阅读模式
英文:

How to define an graph of classes in C++ (field types, getters and setters)

问题

以下是您要翻译的部分:

我正在尝试找出在C++中为表示独立实体并形成对象图或对象网络的类编写字段以及getter和setter方法的正确方法。

保持简单,假设我们想在C++中编写与以下Java类相当的代码。

class Person {

private:
    std::string name; // 1
    Address* address; // 2
    std::vector<Account*> accounts; // 3

public:
    // 1
    const std::string& getName() const { return name; }
    void setName(const std::string& name) { this->name = name; }

    // 2
    Address* getAddress() const { return address; }
    void setAddress(Address* address) { this->address = address; }

    // 3
    const std::vector<Account*>& getAccounts() const { return accounts; }
};

如您所见,我选择了标准的String类型和2个自定义类作为成员字段。这是因为它们是复杂类型。除了名称字段外,其他两个字段被选择来演示典型的多对一关系(人-地址)和一对多关系(人-帐户)。

另外,C++中的String类型(std::string)是一个RAII类型。它通常以字面方式使用,因为它封装了其在堆中实际值的管理。

现在,我不清楚每个字段的正确类型定义是什么,以及如何使用getter和setter暴露它们,同时保持每个对象的生命周期,就像上面的Java示例中一样。

class Person {

    std::string _name;
    // 作为指针的地址?引用?值?shared_ptr?
    // 帐户集合与上述相同

public:
    // 适当的getter、setter?
}

注意1:我不关心像“你为什么要这样做?”或“你为什么想这样做?”这样的答案。问题的重点是建立对如何在C++中构建对象图的清晰理解。有很多合法的原因和应用,比如设计领域模型等。所以是的,感谢您保持问题的焦点。

英文:

I am trying to figure the correct approach on how to write fields as well as getter and setter methods in C++ for classes that represent independent entities and form a graph or network of objects.

Keeping things simple, Lets say that we want to write the equivalent code in C++ of the following class in Java.

public class Person {

	private String name; // 1
	private Address address; // 2
	private List&lt;Account&gt; accounts = new ArrayList&lt;&gt;(); // 3

	// 1
	public String getName() { return name; }
	public void setName(String name) { this.name = name; }

	// 2
	public Address getAddress() { return address; }
	private void setAddress(Address address) { this.address = address; }

	// 3
	public List&lt;Account&gt; getAccounts() { return accounts; }
}

class Address { ... }
class Account { ... }

As you can see I have chosen the standard String type and 2 custom classes as member fields. That is because they are complex types. Besides the name field, the other 2 fields are chosen to demonstrate a typical a many-to-one relationship (person-adress) and one-to-many relationship (person-accounts).

In addition the String type in C++ (std:string) is a RAII type. It used typically in a literal way as it encapsulates the management of its actual value in the heap.

Now, it is not clear to me what would be the correct type definition for each field and how to expose them with getters and setters, while keeping each object's lifetime, in C++ as in the Java example above.

class Person {

	std::string _name;
	// address as pointer? reference? value? shared_ptr?
	// the same as above for the collection of accounts

	public:
	// appropriate getters, setters ?
}

NOTE 1: I am not interested in answers like "why are you doing this?" or "why do you want to do this?". The point of the question is to establish a clear understanding of how we can build a graph of objects in C++. There are plenty legitimate reasons and applications of this, such as designing a domain model, etc. So yes thanks for stinking to the point.

答案1

得分: 1

首先,你混淆了不同的事物。我暂时会忽略关于 getters 和 setters 的部分...

// 地址作为指针?引用?值?shared_ptr?

如果你想要一个 std::string,你就使用 std::string。如果你想要一个 Adress,你就使用 Adress。如果你想要一个值,你就使用一个值。在你的代码中没有显示出你需要其他任何东西。在 C++ 中,大多数生命周期都是自动管理的(与 Java 相比,具有确定性)。

我不是完全确定,但我猜一个适合替代 ArrayList 的东西是 std::vector。然而,不要把它们混淆为相同的东西,甚至不要把它们看作相似的东西。一个 ArrayList<whatever> 包含 Java 的 Object,而一个 std::vector<std::string> 包含的是实际的 std::string。值。

struct Adress {
    std::string city;
};
struct Account {
    std::string password;
};

struct Person { 
    std::string _name;
    Adress adress;
    std::vector<Account> accounts;
};

这就是你需要正确管理对象生命周期的全部内容。析构函数会被自动调用。

关于向 setters 传递参数和从 getters 返回值,你可以查看C++ 核心指南。然而,这部分指南可能会有点压倒性,基本上你需要知道的关于开始使用 getters 和 setters 的所有信息都可以在这里找到。

英文:

First of all, you are conflating different things. I'll ignore the part of getters and setters for a moment...

>// address as pointer? reference? value? shared_ptr?

If you want a std::string then you use a std::string. If you want an Adress then you use an Adress. If you want a value then you use a value.There is no indication in your code that you need anything else. Most lifetimes are mangaged automatically in C++ (and deterministically in constrast to Java).

I am not perfectly certain but I guess a good replace for ArrayList is a std::vector. However, don't confuse them to be the same or even similar. An ArrayList&lt;whatever&gt; contains Java Objects while a std::vector&lt;std::string&gt; does contain acutal std::strings. Values.

struct Adress {
    std::string city;
};
struct Account {
    std::string password;
};

struct Person { 
    std::string _name;
    Adress adress;
    std::vector&lt;Account&gt; accounts;
};

This is all you need to correctly manage lifetime of the objects. Destructors are called automatically.

For passing parameters to setters and returning values from getters you can look at the C++ coreguidelines. However, that part of the guidelines can be a bit overwhelming and basically all you need to know to get started with getters and setters you can find here.

huangapple
  • 本文由 发表于 2020年8月21日 21:26:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/63523785.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定