Java 如何在C++;模板
我有一小部分Java算法,用于玩多回合游戏,如Tictatcoe、Otherlo、Checkers等。我使用Java泛型(自定界类型)来实现这一点,以便能够使用相同的算法,而不必为每个游戏专门更改它们。这里没有显示我使用自定界类型的原因,但是求值函数需要它Java 如何在C++;模板,java,c++,templates,generics,Java,C++,Templates,Generics,我有一小部分Java算法,用于玩多回合游戏,如Tictatcoe、Otherlo、Checkers等。我使用Java泛型(自定界类型)来实现这一点,以便能够使用相同的算法,而不必为每个游戏专门更改它们。这里没有显示我使用自定界类型的原因,但是求值函数需要它 public interface Game<GAME extends Game<GAME>> { GAME copy(); int getCurPlayer(); ... } public c
public interface Game<GAME extends Game<GAME>> {
GAME copy();
int getCurPlayer();
...
}
public class TicTacToe implements Game<TicTacToe> {
...
@Override
public TicTacToe copy() {
...
}
@Override
public int getCurPlayer() {
...
}
...
}
当我尝试编译时,我得到的错误是:
out-of-line definition of 'copy' does not match any declaration in 'TicTacToe'
out-of-line definition of 'cur_player' does not match any declaration in 'TicTacToe'
。。。
对于其他每个纯虚函数也是如此。您的定义也需要将
const
应用于它们。CRTP,正如它在C++中所知道的(奇怪的重复模板模式)是完全有效的C++。
但是,这里不需要virtual
,CRTP用于静态分派功能并自动实现功能
template <typename T>
class Game
{
T& crtp_cast() { return *static_cast<T*>(this); }
const T& crtp_cast() const { return *static_cast<const T*>(this); }
public:
T copy() const { return crtp_cast(); }
int cur_player() const { return crtp_cast().cur_player(); }
...
};
模板
班级游戏
{
T&crtp_cast(){return*static_cast(this);}
const T&crtp_cast()const{return*static_cast(this);}
公众:
T copy()常量{return crtp_cast();}
int cur_player()常量{return crtp_cast().cur_player();}
...
};
注意,在这种情况下,派生类不需要实现“copy”函数,因为复制构造函数将被“copy”自动调用。然而,在一般情况下,由于模板是duck类型的,所以不需要做这种事情,通常您只需要使用标准模板。与Java的泛型不同,C++的模板与继承没有任何关系——可以实例化的类型不必从公共接口继承
template<typename Game> void f(const Game& g) {
std::cout << g.cur_player();
}
class X {
public:
int cur_player() const { return 1; }
};
class Y {
public:
int cur_player() const { return 2; }
};
int main() {
f(X());
f(Y());
}
模板无效f(const Game&g){
STD::CUT< P>你的定义需要应用<代码> const 。CRTP,如C++中已知的(奇怪的重复模板模式)是完全有效的C++。
但是,这里不需要virtual
,CRTP用于静态分派功能并自动实现功能
template <typename T>
class Game
{
T& crtp_cast() { return *static_cast<T*>(this); }
const T& crtp_cast() const { return *static_cast<const T*>(this); }
public:
T copy() const { return crtp_cast(); }
int cur_player() const { return crtp_cast().cur_player(); }
...
};
模板
班级游戏
{
T&crtp_cast(){return*static_cast(this);}
const T&crtp_cast()const{return*static_cast(this);}
公众:
T copy()常量{return crtp_cast();}
int cur_player()常量{return crtp_cast().cur_player();}
...
};
注意,在这种情况下,派生类不需要实现“copy”函数,因为复制构造函数将被“copy”自动调用但是,在一般情况下,由于模板是duck类型的,因此没有必要做这种事情,通常您只需要使用标准模板。与Java泛型不同,C++的模板与继承没有任何关系-可以实例化的类型不必从公共接口继承
template<typename Game> void f(const Game& g) {
std::cout << g.cur_player();
}
class X {
public:
int cur_player() const { return 1; }
};
class Y {
public:
int cur_player() const { return 2; }
};
int main() {
f(X());
f(Y());
}
模板无效f(const Game&g){
std::cout而不是使用泛型/模板,我只会从copy之类的东西传递一个指向游戏的指针,然后如果您真的需要,动态地将其向下转换
例如:
游戏h:
class Game
{
public:
virtual Game* copy() const = 0;
virtual int cur_player() const = 0;
...
};
Tictoe.h:
class TicTacToe : public Game
{
public:
virtual Game* copy() const;
virtual int cur_player() const;
...
};
TicTacToe.cpp:
Game* TicTacToe::copy()
{
...
}
int TicTacToe::cur_player()
{
...
}
按以下方式创建游戏:
TicTacToe ttt;
Game* game = &ttt;
Game* nextGame = game->copy(); // this will call TicTacToe::copy
如果您需要调用TictaToe特定的方法,请将它们添加到游戏中,或者尝试向下播放:
TicTacToe* ttt = dynamic_cast<TicTacToe*>(game);
ttt->TTTSpecificMethod();
TicTacToe*ttt=动态施法(游戏);
ttt->TTTSSpecificMethod();
我不使用泛型/模板,而是通过复制之类的方式传递一个指向游戏的指针,然后如果您真的需要,动态地将其向下转换
例如:
游戏h:
class Game
{
public:
virtual Game* copy() const = 0;
virtual int cur_player() const = 0;
...
};
Tictoe.h:
class TicTacToe : public Game
{
public:
virtual Game* copy() const;
virtual int cur_player() const;
...
};
TicTacToe.cpp:
Game* TicTacToe::copy()
{
...
}
int TicTacToe::cur_player()
{
...
}
按以下方式创建游戏:
TicTacToe ttt;
Game* game = &ttt;
Game* nextGame = game->copy(); // this will call TicTacToe::copy
如果您需要调用TictaToe特定的方法,请将它们添加到游戏中,或者尝试向下播放:
TicTacToe* ttt = dynamic_cast<TicTacToe*>(game);
ttt->TTTSpecificMethod();
TicTacToe*ttt=动态施法(游戏);
ttt->TTTSSpecificMethod();
通过一些修改,自绑定泛型(Java)与奇怪的循环模板模式(C++)等价
template <class T>
class A
{
private:
explicit A(A *temp) {}
public:
explicit A() : A(static_cast<T*>(this)) {}
virtual A* function(T *parameter) = 0;
};
class B final : public A<B>
{
public:
B* function(B *parameter) { return new B(); }
};
class C final
{
};
class D final : public A<C>
{
public: // It occurs compile-time-error
D* function(C *parameter) { return new D(); }
};
class E final : public A<E>
{
public: //"override" specifier will not be accepted due to signature does not match!
E* function(E *parameter) override { return new E(); }
};
class F final : public A<B>
{
public: //You can also assign another relative type but type-self
F* function(B *parameter) { return new F(); }
};
int main()
{
return 0;
}
模板
甲级
{
私人:
显式A(A*temp){}
公众:
显式A():A(static_cast(this)){
虚A*函数(T*参数)=0;
};
B类期末考试:公共A
{
公众:
B*函数(B*参数){返回新的B();}
};
丙级决赛
{
};
D类期末考试:公共A
{
public://发生编译时错误
D*函数(C*参数){返回新的D();}
};
E级期末考试:公共A
{
public://“override”说明符将不被接受,因为签名不匹配!
E*函数(E*参数)重写{返回新的E();}
};
F类期末考试:公共A
{
public://您还可以指定另一个相对类型,但不能指定self类型
F*函数(B*参数){返回新的F();}
};
int main()
{
返回0;
}
通过一些修改,自绑定泛型(Java)与奇怪的循环模板模式(C++)等价
template <class T>
class A
{
private:
explicit A(A *temp) {}
public:
explicit A() : A(static_cast<T*>(this)) {}
virtual A* function(T *parameter) = 0;
};
class B final : public A<B>
{
public:
B* function(B *parameter) { return new B(); }
};
class C final
{
};
class D final : public A<C>
{
public: // It occurs compile-time-error
D* function(C *parameter) { return new D(); }
};
class E final : public A<E>
{
public: //"override" specifier will not be accepted due to signature does not match!
E* function(E *parameter) override { return new E(); }
};
class F final : public A<B>
{
public: //You can also assign another relative type but type-self
F* function(B *parameter) { return new F(); }
};
int main()
{
return 0;
}
模板
甲级
{
私人:
显式A(A*temp){}
公众:
显式A():A(static_cast(this)){
虚A*函数(T*参数)=0;
};
B类期末考试:公共A
{
公众:
B*函数(B*参数){返回新的B();}
};
丙级决赛
{
};
D类期末考试:公共A
{
public://发生编译时错误
D*函数(C*参数){返回新的D();}
};
E级期末考试:公共A
{
public://“override”说明符将不被接受,因为签名不匹配!
E*函数(E*参数)重写{返回新的E();}
};
F类期末考试:公共A
{
public://您还可以指定另一个相对类型,但不能指定self类型
F*函数(B*参数){返回新的F();}
};
int main()
{
返回0;
}
您从不说明什么不起作用。这根本不清楚为什么不起作用。您有什么问题(编译器错误?)没有“自绑定类型”的用处在Java中。你的代码在公共界面游戏中同样有效。你从不说什么不起作用。为什么不起作用一点也不明显。你有什么问题(编译器错误?)没有“自绑定类型”的用处在Java中。您的代码与公共界面游戏一样有效
谢谢,它有效!您