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

问题描述 投票:-2回答:1

我开始学习C ++并且来自C#背景我遇到了很多问题。

我想要做的是尝试使用C ++复制与我在以下C#片段中所做的完全相同的事情。这只是MVP模式的一个简单实现,我使用了很多。

我尝试了许多不同的方法,使用适当和现代的C ++来完成这项工作,但它不断给我编译错误,我不能正确理解。其中大多数是由于我无法找到将接口作为构造函数参数传递的正确方法,也将接口存储为类的字段。有人可以将这个C#代码翻译成适当的C ++代码,或者至少给我一些建议吗?提前致谢。

注意:我正在尝试使用类声明和带有实际实现的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;
}

这是我正在尝试编译的C ++代码。为了清晰和简洁起见,我把所有内容放在没有.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);
}
c# c++ interface mvp
1个回答
2
投票

elgonzo是对的。你不应该通过翻译来开始学习语言,尤其是介于C#和C ++之间。它们之间唯一的相似之处是关键字的命名约定。

在这种情况下,重要的区别(除了如何在C ++中声明接口)是C ++中的所有类型都是按值保存,而C#类是通过引用保存的。您无法使用任何一种语言创建接口实例(即您无法在C#中执行new IGameView())。

因此,您的Game类型不能按值保存接口类型。它需要是指针或引用。这与C#完全不同,我建议你像其他评论者一样说并首先学习C ++基础知识,然后再回过头来看看。

编辑:

这是您发布的C ++代码的工作形式。它有评论解释为什么/何时做它做的事情。

// 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;
}
© www.soinside.com 2019 - 2024. All rights reserved.