C++ 从抽象类型定义 class 成员
C++ defining class member from an abstract type
我正在尝试将一些代码从 C# 移动到 C++,并且我正在尝试找到实现 class 层次结构的最佳方法。
在 C# 中,在派生的 class 中,您可以从抽象基础 class 类型定义一个 class 成员变量。但是,当我搜索我的 C++ 资源时,似乎我只能定义
来自另一个 class 中抽象类型的指针或引用变量(否则编译器显示:"cannot instantiate abstract class"),但这可能与定义对象的生命周期有问题,因为生命周期是在 class 使用它。关于将 C# 代码映射到 C++ 时应如何实现这种继承层次结构的任何建议?
Class Person
{
public:
virtual double getSalary() = 0;
private:
int rank;
}
Class Teacher : public Person
{
public:
double getSalary();
private:
Person manager; /*<-- Compile error: error C2259: 'Person' : cannot instantiate abstract class */
}
直接回答你的问题:你不能定义抽象类型的class成员变量。在 C++ 中,成员主要由内存大小定义,并且由于继承 class 可能需要不同数量的内存,所以这是不可能的。
但是,您可以使用指针或引用。
你的情况:
class Teacher : public Person
{
public:
double getSalary();
private:
Person* manager;
}
这存储了指向 Person
的指针,并且由于 Teacher
是一个 Person
,类型为 [=16= 的对象] 将是一个合法的目标。
示例性使用:我们创建一个setter
Teacher::set_manager(Person* manager)
{
this->manager = manager;
}
并称其为
Teacher a;
Teacher* b = new Teacher;
a.set_manager(b);
(我使用 setter 作为最简单的示例,不一定是因为我建议这样做。)
也可以:
Teacher a;
Person* b = new Teacher;
a.set_manager(b);
(a
需要是 Teacher
,但是,因为我们需要方法 set_manager
,如果我们不想转换)
顺便说一下,在这里做的更好的事情是使用智能指针。阅读 std::shared_ptr
和相关内容。看起来像
std::shared_ptr<Person> manager;
此处的重要区别:如果您习惯了垃圾守护进程,则需要手动释放原始指针的内存,而智能指针会在不再指向对象时自动释放内存。
也就是说,您似乎认为这些语言比实际情况更相似。我的建议是从头开始,使用 C++ 的基础教程,即使您碰巧是一位有成就的 C# 程序员。
我正在尝试将一些代码从 C# 移动到 C++,并且我正在尝试找到实现 class 层次结构的最佳方法。 在 C# 中,在派生的 class 中,您可以从抽象基础 class 类型定义一个 class 成员变量。但是,当我搜索我的 C++ 资源时,似乎我只能定义 来自另一个 class 中抽象类型的指针或引用变量(否则编译器显示:"cannot instantiate abstract class"),但这可能与定义对象的生命周期有问题,因为生命周期是在 class 使用它。关于将 C# 代码映射到 C++ 时应如何实现这种继承层次结构的任何建议?
Class Person
{
public:
virtual double getSalary() = 0;
private:
int rank;
}
Class Teacher : public Person
{
public:
double getSalary();
private:
Person manager; /*<-- Compile error: error C2259: 'Person' : cannot instantiate abstract class */
}
直接回答你的问题:你不能定义抽象类型的class成员变量。在 C++ 中,成员主要由内存大小定义,并且由于继承 class 可能需要不同数量的内存,所以这是不可能的。
但是,您可以使用指针或引用。
你的情况:
class Teacher : public Person
{
public:
double getSalary();
private:
Person* manager;
}
这存储了指向 Person
的指针,并且由于 Teacher
是一个 Person
,类型为 [=16= 的对象] 将是一个合法的目标。
示例性使用:我们创建一个setter
Teacher::set_manager(Person* manager)
{
this->manager = manager;
}
并称其为
Teacher a;
Teacher* b = new Teacher;
a.set_manager(b);
(我使用 setter 作为最简单的示例,不一定是因为我建议这样做。)
也可以:
Teacher a;
Person* b = new Teacher;
a.set_manager(b);
(a
需要是 Teacher
,但是,因为我们需要方法 set_manager
,如果我们不想转换)
顺便说一下,在这里做的更好的事情是使用智能指针。阅读 std::shared_ptr
和相关内容。看起来像
std::shared_ptr<Person> manager;
此处的重要区别:如果您习惯了垃圾守护进程,则需要手动释放原始指针的内存,而智能指针会在不再指向对象时自动释放内存。
也就是说,您似乎认为这些语言比实际情况更相似。我的建议是从头开始,使用 C++ 的基础教程,即使您碰巧是一位有成就的 C# 程序员。