我们的学习书中有一个关于对象函数的问题。 c ++中有一个代码,这个问题想让我们填补空白。代码如下
videoPreviewLayer
理想的结果是
template <typename Arg, typename Ret>
class FuncObj {
public:
typedef Arg argType;
typedef Ret retType;
virtual Ret operator()(Arg) = 0;
};
class DivideBy : public FuncObj<int, double> {
protected:
int divisor;
public:
DivideBy(int d) {
this->divisor = d;
}
double operator()(int x) {
return x/((double)divisor);
}
};
class Truncate : public FuncObj<double, int> {
public:
int operator()(double x) {
return (int) x;
}
};
template < typename Ftype , typename Gtype >
class Compose : public FuncObj <typename Gtype :: argType, typename Ftype :: retType > {
protected:
Ftype *f; Gtype *g;
public:
Compose(Ftype f,Gtype g) {
--------- =f;
--------- =g;
}
---------- operator()(____________x) {
return (_________)((________)(__________)); }
};
我真的不知道如何完成这段代码,那么我们应该使用c ++的哪些功能或概念来完成这项工作?如果有关于此主题的进一步研究链接,请写下来。 谢谢。
答案 0 :(得分:5)
这段代码很糟糕(如果那是材料的平均质量,那么学习书也是如此)。
首先,void main()
不是main
的有效签名。在这种情况下,它应该为int main()
。其次,如果假设Compose
是使用指针构造的,则其构造函数应声明为Compose(Ftype* f, Gtype* g)
,而不是Compose(Ftype f, Gtype g)
。第三,代码应包括<iostream>
并在前缀cout
和endl
的前面加上std::
(或使用using namespace std
,但这仍然很糟糕)。最后,所有new
应该有一个对应的delete
,但更好的方法是使用智能指针,或者根本不使用指针。
无论如何,填空都是相对简单的。
构造函数将这样写:
Compose(Ftype f,Gtype g) {
this->f = f;
this->g = g;
}
...这很糟糕,因为它在不需要时强制使用this->
(以其他方式命名参数,或使用成员初始化器列表)。
呼叫操作符将这样写:
typename Ftype::retType operator()(typename Gtype::argType x) {
return (*f)((*g)(x));
}
参数类型和返回类型是作为模板参数传递给基类FuncObj
的那些类型,然后调用仅组成f
和g
。
Demo。
不使用任何指针的更好的代码如下所示:
template<typename Ftype, typename Gtype>
class Compose : public FuncObj<typename Gtype::argType, typename Ftype::retType> {
protected:
Ftype f;
Gtype g;
public:
Compose(Ftype f, Gtype g)
: f(f), g(g) {
}
typename Ftype::retType operator()(typename Gtype::argType x) {
return f(g(x));
}
};
int main() {
auto d = DivideBy(2);
auto t = Truncate();
auto c1 = Compose(d, t);
auto c2 = Compose(t, d);
std::cout << c1(100.7) << "\n";
std::cout << c2(11) << "\n";
}
Demo。
不要使用类似Java的初始化方法Type *var = new Type(args);
,而要使用值(auto var = Type(args);
或Type var(args)
)。 C ++不是Java。
请注意,您甚至不需要为Compose
指定模板参数:它们是从构造函数参数中推导出来的。
答案 1 :(得分:0)
填充空白不是很困难,但是我想说代码风格确实很糟糕。
template <typename Ftype, typename Gtype>
class Compose : public FuncObj<typename Gtype ::argType, typename Ftype ::retType>
{
protected:
Ftype *f;
Gtype *g;
public:
Compose(Ftype *f, Gtype *g) : f(f), g(g){}; // Prefer constructor initialization list.
typename Ftype ::retType operator()(typename Gtype ::argType arg)
{
return (*f)((*g)(arg));
}
};
int main(int argc, char const *argv[])
{
auto *d = new DivideBy(2);
auto *t = new Truncate();
auto *c1 = new Compose<DivideBy, Truncate>(d, t);
auto *c2 = new Compose<Truncate, DivideBy>(t, d);
cout << (*c1)(100.7) << endl;
cout << (*c2)(11) << endl;
delete d;
d = nullptr;
delete t;
t = nullptr;
delete c1;
c1 = nullptr;
delete c2;
c2 = nullptr; // You need to be very careful with bare pointers.Use unique_ptr and shared_ptr in modern C++.
}