我必须创建继承自抽象类的类实例。
我的代码非常简单。它应该基于抽象类创建对象类的实例。抽象类也是模板类。然后我需要将此对象放入storage
类,该类保存指向对象的指针。就这样。这项任务是某种功课。
甚至可以基于抽象类创建类的实例吗?
如果是的话 - 我做错了什么? 如果不是 - 我怎么能让它变得相似?
#include <iostream>
#include <string>
#include <memory>
// using namespace std;
template<typename type1, typename type2, typename type3> class INTERFACE {
protected:
type1 x;
type2 y;
type3 name;
public:
virtual type1 setX() = 0;
virtual type2 setY() = 0;
};
class child : public INTERFACE<int, float, std::string> {
public:
child(std::string z) {
this->name = z;
}
int setX(int x) {
this->x = x;
}
float setY(float y) {
this->y = y;
}
};
class storage {
private:
std::shared_ptr<child> childPTR;
public:
void setPTR(const std::shared_ptr<child> & pointer) {
this->childPTR = pointer;
}
};
int main(){
std::shared_ptr<child> newChild(new child("xxx"));
storage testStorage;
testStorage.setPTR(newChild);
return 0;
}
编译错误:
templates.cpp: In function ‘int main()’:
templates.cpp:44:52: error: invalid new-expression of abstract class type ‘child’
std::shared_ptr<child> newChild(new child("xxx"));
^
templates.cpp:18:7: note: because the following virtual functions are pure within ‘child’:
class child : public INTERFACE<int, float, std::string> {
^
templates.cpp:14:23: note: type1 INTERFACE<type1, type2, type3>::setX() [with type1 = int; type2 = float; type3 = std::__cxx11::basic_string<char>]
virtual type1 setX() = 0;
^
templates.cpp:15:23: note: type2 INTERFACE<type1, type2, type3>::setY() [with type1 = int; type2 = float; type3 = std::__cxx11::basic_string<char>]
virtual type2 setY() = 0;
答案 0 :(得分:1)
好的,我将按照从主函数开始执行的顺序检查代码中的错误。
shared_ptr
,您应使用专用函数make_shared
。如果可能的话,最好不要使用new
并将内存处理留给为此目的而编写的类(例如您正在使用的shared_ptr
)。child
对象并将其另存为ITERFACE
。将派生类保存为其基类引用/指针是有效的。unique_ptr
课程中使用shared_ptr
代替storage
。该类的名称表示它存储数据,因此拥有它。storage
应将其数据保存为unique_ptr
,因此newChild也应为unique_ptr
,然后只需将所有权与storage
交换shared_ptr
。他们负责记忆,您需要调用get
或swap
等专用函数来操纵他们持有的数据。INTERFACE
中,您有2种类型为type2 setX()
的虚拟集方法。人们可以期望他们将属性赋予他们应该设置的值作为参数。您在那里使用的= 0
意味着该方法未实现,并且继承类应该实现它。这是正确的,因为名称INTERFACE
表示,它只是一个界面,公开显示继承它的类可以做什么,而实际上没有任何功能。child
类中的集合函数缺少override
关键字,它告诉编译器这些方法应该覆盖基类中的函数。由于你的基础classe的实现错误,它没有告诉你任何事情。我希望我能解决所有问题。如果我发现任何其他内容或其他人提到任何内容,我会将其添加到列表中。以下是修复所有问题的示例:
#include <iostream>
#include <string>
#include <memory>
template<typename Type1, typename Type2, typename Type3>
class Interface {
protected:
Type1 x;
Type2 y;
Type3 name;
public:
// setters with proper signature now
virtual void setX(Type1) = 0;
virtual void setY(Type2) = 0;
};
class Child: public Interface<int, float, std::string> {
public:
Child(const std::string& z) { name = z; };
void setX(int val) override { x = val; }
void setY(float val) override { y = val; }
};
class Storage {
// private keyword not needed
// you also need to specify template arguments of the interface here
std::unique_ptr<Interface<int, float, std::string>> _interface;
// convention of prefixing private members with _
public:
void setPointer(std::unique_ptr<Interface<int, float, std::string>>&& pointer) {
// transfers ownership of that memory to _interface
_interface = std::move(pointer);
}
};
int main() {
// make_unique creates an instance of child, passing it's arguments
// to child's constructor and saves it inside an interface pointer
std::unique_ptr<Interface<int, float, std::string>> newChild = std::make_unique<Child>("xxx");
Storage testStorage;
// here you must move the ownership to the setPointer function
testStorage.setPointer(std::move(newChild));
return 0;
}
我还重构了你的代码,以遵循我喜欢在我的代码中使用的约定。希望我已经解决了所有问题,如果您有任何其他问题,请随时提出。
P.S。:我现在无法访问C ++编译器,所以希望我提供的代码可以毫无问题地编译。
答案 1 :(得分:0)
您有两个主要问题:
在你的派生类中,你必须返回“setX()和Y”的值,但是我不会因为这个名字暗示它只是“sets”,所以不是getter。
public:
virtual auto setX(type1 x) ->decltype(x) = 0;
virtual auto setY(type2 y) ->decltype(y) = 0;
...
int setX(int x) {
this->x = x;
return x;
}
float setY(float y) {
this->y = y;
return y;
}