在 dependent class 的构造函数中使用抽象 class 作为数据类型
using abstract class as data type in constructor of dependent class
对于大学项目,我们必须创建多个 classes,所有这些都取决于抽象 class 函数。
但是在尝试定义 class Compose
时,它必须组合作为构造函数参数传递的两个不同函数,我遇到了几个问题,如下所示。
在这种情况下,我怎样才能毫无问题地使用我的抽象 class 作为数据类型?
摘要ClassFunction
:
class Function{
protected:
double _a, _b, _c, _m;
public:
Function(double a, double b, double c, double m): _a(a), _b(b), _c(c), _m(m){}
virtual double evaluate(double x) =0;
void print(){ for(double i=0.0; i==1.0; i+=0.1) cout << "Wert: " << i << ", Ergebnis: " << evaluate(i) << endl;}
};
Class Compose
:
class Compose:public Function{
private:
Function *_f1, *_f2;
public:
Compose(Function & f1, Function & f2):Function(0,0,0,0), _f1(f1), _f2(f2){}
double evaluate(double x){}
};
错误信息:
21:54:02 **** Incremental Build of configuration Debug for project Aufgabe_10_1 ****
Info: Internal Builder is used for build
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -o "src\Aufgabe_10_1.o" "..\src\Aufgabe_10_1.cpp"
..\src\Aufgabe_10_1.cpp: In constructor 'Compose::Compose(Function&, Function&)':
..\src\Aufgabe_10_1.cpp:37:7: error: cannot convert 'Function' to 'Function*' in assignment
_f1 = f1;
^
..\src\Aufgabe_10_1.cpp:38:7: error: cannot convert 'Function' to 'Function*' in assignment
_f2 = f2;
^
..\src\Aufgabe_10_1.cpp: In member function 'virtual double Compose::evaluate(double)':
..\src\Aufgabe_10_1.cpp:40:28: warning: no return statement in function returning non-void [-Wreturn-type]
double evaluate(double x){}
^
21:54:03 Build Finished (took 423ms)
第一个问题:
你一半的错误可以减少为这样的事情:
Function &a = ...;
Function *b = a;
根据您上面显示的内容,这没有任何意义。
第二题:
Function
没有采用零参数的构造函数。所以需要在Compose
的构造函数中显式调用它的一个构造函数。也许是这样的:
class Compose:public Function{
private:
Function *_f1, *_f2;
public:
Compose(Function *f1, Function *f2): Function(0,1,2,3), _f1(f1), _f2(f2) {}
double evaluate(double x) {}
};
指针和引用可以引用抽象类型。在您的 Compose
class 中,您已经声明了指针成员 _f1
和 _f2
,这很好。但是,您不能将引用分配给指针,因此您应该更改 Compose
的构造函数以也将指针作为参数。
class Compose : public Function
{
private:
Function *_f1, *_f2; // these are pointers
public:
Compose(Function & f1, Function & f2) : _f1(f1), _f2(f2)
{ // ^^^ references here ^^^ ^^^ problem there ^^^
}
// ...
};
这可行:
Compose(Function * f1_ptr, Function * f2_ptr) : _f1(f1_ptr), _f2(f2_ptr)
{ // ^^^ pointers here ^^^ ^^^ pointers there ^^^
}
但是像这样使用原始指针是一个问题。谁将负责再次 delete
ing 他们?现代 C++ 尽可能避免使用此类原始指针,转而采用所谓的 智能指针 ,它们会进行引用计数并在最后一个引用被销毁时自动 delete
指针。因此,你的class更好的设计应该是这样的。
#include <memory>
class Compose : public Function
{
private:
std::shared_ptr<Function> f1_;
std::shared_ptr<Function> f2_;
public:
Compose(std::shared_ptr<Function> f1,
std::shared_ptr<Function> f2) : f1_ {f1}, f2_ {f2}
{
}
// ...
};
在这种情况下,您不必担心为 Compose
编写析构函数,而且还可以确保您永远不会取消引用无效指针。
您可以在此处了解有关使用智能指针进行资源管理的更多信息:
- 维基百科:Resource Acquisition Is Initialization
cppreference.com
: RAII
- 堆栈溢出:RAII and smart pointers in C++
- Bjarne Stroustrup:Make Simple Tasks Simple!(从 30:30 开始)
对于大学项目,我们必须创建多个 classes,所有这些都取决于抽象 class 函数。
但是在尝试定义 class Compose
时,它必须组合作为构造函数参数传递的两个不同函数,我遇到了几个问题,如下所示。
在这种情况下,我怎样才能毫无问题地使用我的抽象 class 作为数据类型?
摘要ClassFunction
:
class Function{
protected:
double _a, _b, _c, _m;
public:
Function(double a, double b, double c, double m): _a(a), _b(b), _c(c), _m(m){}
virtual double evaluate(double x) =0;
void print(){ for(double i=0.0; i==1.0; i+=0.1) cout << "Wert: " << i << ", Ergebnis: " << evaluate(i) << endl;}
};
Class Compose
:
class Compose:public Function{
private:
Function *_f1, *_f2;
public:
Compose(Function & f1, Function & f2):Function(0,0,0,0), _f1(f1), _f2(f2){}
double evaluate(double x){}
};
错误信息:
21:54:02 **** Incremental Build of configuration Debug for project Aufgabe_10_1 ****
Info: Internal Builder is used for build
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -o "src\Aufgabe_10_1.o" "..\src\Aufgabe_10_1.cpp"
..\src\Aufgabe_10_1.cpp: In constructor 'Compose::Compose(Function&, Function&)':
..\src\Aufgabe_10_1.cpp:37:7: error: cannot convert 'Function' to 'Function*' in assignment
_f1 = f1;
^
..\src\Aufgabe_10_1.cpp:38:7: error: cannot convert 'Function' to 'Function*' in assignment
_f2 = f2;
^
..\src\Aufgabe_10_1.cpp: In member function 'virtual double Compose::evaluate(double)':
..\src\Aufgabe_10_1.cpp:40:28: warning: no return statement in function returning non-void [-Wreturn-type]
double evaluate(double x){}
^
21:54:03 Build Finished (took 423ms)
第一个问题:
你一半的错误可以减少为这样的事情:
Function &a = ...;
Function *b = a;
根据您上面显示的内容,这没有任何意义。
第二题:
Function
没有采用零参数的构造函数。所以需要在Compose
的构造函数中显式调用它的一个构造函数。也许是这样的:
class Compose:public Function{
private:
Function *_f1, *_f2;
public:
Compose(Function *f1, Function *f2): Function(0,1,2,3), _f1(f1), _f2(f2) {}
double evaluate(double x) {}
};
指针和引用可以引用抽象类型。在您的 Compose
class 中,您已经声明了指针成员 _f1
和 _f2
,这很好。但是,您不能将引用分配给指针,因此您应该更改 Compose
的构造函数以也将指针作为参数。
class Compose : public Function
{
private:
Function *_f1, *_f2; // these are pointers
public:
Compose(Function & f1, Function & f2) : _f1(f1), _f2(f2)
{ // ^^^ references here ^^^ ^^^ problem there ^^^
}
// ...
};
这可行:
Compose(Function * f1_ptr, Function * f2_ptr) : _f1(f1_ptr), _f2(f2_ptr)
{ // ^^^ pointers here ^^^ ^^^ pointers there ^^^
}
但是像这样使用原始指针是一个问题。谁将负责再次 delete
ing 他们?现代 C++ 尽可能避免使用此类原始指针,转而采用所谓的 智能指针 ,它们会进行引用计数并在最后一个引用被销毁时自动 delete
指针。因此,你的class更好的设计应该是这样的。
#include <memory>
class Compose : public Function
{
private:
std::shared_ptr<Function> f1_;
std::shared_ptr<Function> f2_;
public:
Compose(std::shared_ptr<Function> f1,
std::shared_ptr<Function> f2) : f1_ {f1}, f2_ {f2}
{
}
// ...
};
在这种情况下,您不必担心为 Compose
编写析构函数,而且还可以确保您永远不会取消引用无效指针。
您可以在此处了解有关使用智能指针进行资源管理的更多信息:
- 维基百科:Resource Acquisition Is Initialization
cppreference.com
: RAII- 堆栈溢出:RAII and smart pointers in C++
- Bjarne Stroustrup:Make Simple Tasks Simple!(从 30:30 开始)