简体   繁体   English

如何正确使用 C++ 中的构造函数和方法中的接口?

[英]How do I use interfaces in constructors and methods in C++ properly?

I'm starting to learn C++ and coming from a C# background I'm having a lot of problems.我开始学习 C++ 并且来自 C# 背景我遇到了很多问题。

What I want to do is trying to replicate exactly the same thing that I'm doing in the following C# snippet, with C++.我想要做的是尝试使用 C++ 复制我在以下 C# 代码段中所做的完全相同的事情。 This is just a simple implementation of the MVP pattern, which I use quite a lot.这只是 MVP 模式的一个简单实现,我经常使用它。

I tried in many different ways to make this work with proper and modern C++ but it's constantly giving me compilation errors which I do not understand properly.我尝试了许多不同的方法来使用适当的现代 C++ 来完成这项工作,但它不断给我带来我无法正确理解的编译错误。 Most of them are due to the fact that I'm not able to find a proper way to pass an Interface as a constructor parameter and also to store an Interface as a field of a class.其中大多数是由于我无法找到将接口作为构造函数参数传递并将接口存储为类的字段的正确方法。 Could someone translate this C# code into a proper C++ code, or at least give me some advice please?有人可以将此 C# 代码翻译成正确的 C++ 代码,或者至少给我一些建议吗? Thanks in advance.提前致谢。

NOTE: I'm trying to make headers files with only classes declaration and cpp files with actual implementation.注意:我正在尝试制作只有类声明的头文件和具有实际实现的 cpp 文件。

// This is my C# implementation that I want to convert in C++

public class Program
{
    public static void Main()
    {
        IGameView view = new GameView();
        Game game = new Game(view);
        view.SetPresenter(game);
    }
}

public interface IGameView
{
    void SetPresenter(Game game);
}

public class GameView : IGameView
{
    public void SetPresenter(Game game)
    {
        _game = game;
    }

    Game _game;
}

public class Game
{
    public Game(IGameView view)
    {
        _view = view;
    }

    IGameView _view;
}

This is the C++ code that I'm trying to make compile.这是我试图编译的 C++ 代码。 I've put everything here without .h and .cpp for clarity and brevity, but as I said I'm actually separating classes from implementation.为清晰和简洁起见,我把所有内容都放在这里,没有 .h 和 .cpp,但正如我所说,我实际上是将类与实现分开。

class Game
{
public:
    (IGameView& view) : _view(view)
    { }

    Game operator=(const Game &);

private:
    IGameView& _view;
};

class IGameView
{
public:
    virtual ~IGameView() {}

    virtual void SetPresenter(const Game) = 0;
};

class GameView : public IGameView
{
public:

    GameView();

    void SetPresenter(const Game game) override
    {
        _game = game;
    }

private:
    Game& _game;
};

int main()
{
    IGameView view;
    Game game(view);
    view.SetPresenter(game);
}

elgonzo is right.埃尔贡佐是对的。 You shouldn't start learning a language by doing translations, esp.你不应该通过翻译来开始学习语言,尤其是。 going between something like C# and C++.介于 C# 和 C++ 之类的东西之间。 The only similarity between them is naming conventions for keywords.它们之间唯一的相似之处是关键字的命名约定。

In this case the important difference (aside from how to declare interfaces in C++) is that all types in C++ are held by value, whereas C# classes are held by reference.在这种情况下,重要的区别(除了如何在 C++ 中声明接口)是 C++ 中的所有类型都按值保存,而 C# 类则按引用保存。 You can't create an instance of an interface in either language (ie you can't do new IGameView() in C#).你不能用任何一种语言创建接口的实例(即你不能在 C# 中执行new IGameView() )。

Thus, your Game type can't hold an interface type by value.因此,您的Game类型不能按值保存接口类型。 It needs to be a pointer or reference instead.它需要是一个指针或引用。 This is all very different from C#, and I suggest you do as the other commenters have said and learn C++ fundamentals first and come back to this later.这与 C# 完全不同,我建议您按照其他评论者所说的去做,先学习 C++ 基础知识,然后再回来学习。

Edit:编辑:

Here's a working form of the C++ code you posted.这是您发布的 C++ 代码的工作形式。 It has comments explaining why/when to do what it does.它有解释为什么/何时做它所做的事情的评论。

// C++ requires declaring types before you use them.
// if we want to use Game before defining it we must at least declare that it exists.
class Game;

// this is an interface because it contains abstract (pure virtual) functions.
// you cannot create an instance of an abstract type - but you can make a reference or pointer to one.
struct IGameView
{
    // we might want polymorphic deletion - so to be safe we'll make a virtual dtor.
    virtual ~IGameView() {};

    // Game is probably expensive to copy - pass it by reference.
    // = 0 makes this an abstract method, which makes this an abstract type.
    virtual void SetPresenter(Game &game) = 0;
};

// --------------------------------------------

class Game
{
public:
    // take a reference to the (interface) object to use (we can't pass an abstract type by value)
    Game(IGameView &view) : _view(view) { }

private:
    // hold a reference to the IGameView (interface) object.
    // if you ever wanted this to refer to something else this would need to be pointer instead.
    // references are kind of like pointers that cannot be repointed to something else.
    IGameView &_view;
};

class GameView : public IGameView
{
public:
    GameView();

    virtual void SetPresenter(Game &game) override
    {
        _game = &game;
    }

private:
    // hold a pointer to the Game object.
    // this has to be a pointer because SetPresenter() needs to be able to repoint it (refences can't do that).
    // for safety, initialize this to null.
    Game *_game = nullptr;
};

// ---------------------------------------------

int main()
{
    GameView view; // create the game view to use
    Game game(view); // create the game object and use that view

    view.SetPresenter(game); // set the view to use the game object

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM