【问题标题】:c++ interfaces (class) to hide the real identity (instantiation)c++接口(类)隐藏真实身份(实例化)
【发布时间】:2017-12-05 13:24:53
【问题描述】:

我想知道是否有人可以解释我如何使用接口。 通常,接口应在层和架构对象之间的所有情况下使用(允许可测试性、清晰的结构/架构、团队独立工作......)

我还不明白的是,包含依赖项.. 我仍然需要实例化对象 Test 本身,因此需要将它直接包含在上面的层(arch)中。但我宁愿不知道那里发生了什么,只使用界面。

去这里的路是什么? 有人有一个具体的例子吗(例如:HAL::Timer 作为对象,HAL:IF_Timer 作为接口,中间件/应用程序是什么来创建这样的对象并使用它?

// =============== IF_Test.hpp =======================

#ifndef IF_Test_hpp
#define IF_Test_hpp

#include <stdio.h>

class I_Test
{
public:
    I_Test() { };
    virtual ~I_Test() { };
    virtual std::string& toString() = 0;
};

#endif /* IF_Test_hpp */


// =============== Test.hpp =========================

#ifndef Test_hpp
#define Test_hpp

#include <stdio.h>
#include "IF_Test.hpp"

class Test : public I_Test
{
    std::string myName;
public:
    Test();
    ~Test();
    std::string& toString();
};

#endif /* Test_hpp */


// =============== Test.cpp =========================

#include <iostream>
#include <cstdio>
#include <string>

#include "Test.hpp"

Test::Test()
: myName("PeterParkerIsBatman")
{
    std::cout << "Test\n";
}

Test::~Test()
{
    std::cout << "!Test\n";
}

std::string& Test::toString()
{
    return myName;
};


// =============== main.cpp =========================

#include <iostream>

#include "IF_Test.hpp"
/** HERE i still need to include the 
concrete class object, which id likte NOT to do 
(Or do i want this and why?) */
#include "Test.hpp" 

int main(int argc, const char * argv[])
{
    I_Test * obj = new(Test);
    obj->toString();

    std::cout << "Hello, World!\n";

    return 0;
}

【问题讨论】:

  • C++ 中没有接口
  • 旁白 - I_TEST 需要一个虚拟析构函数
  • 我知道,但是类中的纯虚成员函数作为接口的选项??
  • 通常,接口的消费者不会实例化具体类型。
  • 所以可以说我有一个到硬件基本定时器的接口(setDelay()、start()、attach()、stop()、...),然后是一个实现定时器的类。在这种情况下,接口几乎没用,因为我无论如何都需要包含 Timer 类??

标签: c++ class interface embedded


【解决方案1】:

通过引用抽象类成员ITimer,您可以在Scheduler 不了解mTimer 实现的地方获得您正在寻找的抽象层。

// =============== ITimer.h =======================

class ITimer {
    public:
        virtual double time() = 0;
};

// =============== Timer_A.h =======================

//#include ITimer.h

class Timer_A : public ITimer {
    public:
        double time() override {
            /* One way .. */
            return {};
        }
};

// =============== Timer_B.h =======================

//#include ITimer.h

class Timer_B : public ITimer {
    public:
        double time() override {
            /* Another way .. */   
            return {};
        }
};

// =============== Scheduler.h =======================

//#include ITimer.h     <-- No mention of any specific implementation of the ITimer abstract class

class Scheduler{

public:
    Scheduler(ITimer& timer)
    : mTimer(timer)
    {}

    void run (){
        double time = mTimer.time();
        /* etc .. */
    }

    private:
    ITimer& mTimer;
};

// =============== main.cpp =======================

#include Timer_A.h
#include Timer_B.h
#include Manager.h

int main()
{
    Timer_A timerA;
    Timer_B timerB;

    Scheduler schedulerA(timerA);
    Scheduler schedulerB(timerB);
}

您可以拥有尽可能多的层,其中包含包含实现的文件(Timer_A.hTimer_B.h)的唯一位置是最高级别。

正如您所说,这让您可以非常轻松地更改具体类,并允许使用 gmock 进行强大的测试。

【讨论】:

  • 感谢您的示例!帮助总是超过解释它;)
猜你喜欢
  • 2013-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-30
  • 2019-06-30
  • 2015-04-07
  • 2012-01-22
  • 1970-01-01
相关资源
最近更新 更多