是否可以实例化没有指针的接口?

时间:2013-07-19 13:01:25

标签: c++ polymorphism

我的情况如下:在我的大型程序中,我想创建一个接口来从imagesource抓取帧。但是,在程序中,我事先并不知道是否要从相机或视频文件中获取帧。但我想有一个界面处理视频文件和相机帧相同。总的来说,这需要很多代码来实现,因此我将提供一个非常简短的例子。

这是界面的例子:

class Input {

    public :

        virtual void
        get_frame() = 0;
};

这是一个派生类,应该从相机中抓取帧。

class CameraInput: public Input {

    public :
        void get_frame();
};

这是应该打开视频文件并从文件中抓取帧的类。

class VideoInput: public Input {

    public :

        void get_frame();

};

以下是Input派生类中get_frame的定义。正如您所看到的,它们“产生”了不同类型的视频帧。

void
CameraInput::get_frame(){
    std::cout << "camera-frame" << std::endl;
};

void
VideoInput::get_frame() {
    std::cout << "video-frame" << std::endl;
};

这是实例化CameraInputVideoInput类型的对象的代码。

编辑添加的共享指针

typedef enum { VIDEO, CAMERA } input_type ;
std::shared_ptr<Input> framegrabber;
/*Does this have to be a pointer?*/

/*In my program I don't know this in advance.*/
input_type my_input = CAMERA;

switch ( my_input ){
    case CAMERA:
        framegrabber = std::shared_ptr<Input>(new CameraInput);
        break;
    case VIDEO:
        framegrabber = std::shared_ptr<Input>(new VideoInput);
        break;
    default:
        /*error handling here*/
        break;
};

framegrabber->get_frame();

在stackoverflow上,我在c ++的答案中多次读过,除非有人确实需要,否则不应该使用指针。这就是我的问题来源,是否可以更好地在不使用Input*的情况下重写上面的代码,或者这是必须使用指针的情况之一?

亲切的问候,

2 个答案:

答案 0 :(得分:3)

  

在stackoverflow上,我在c ++的答案中多次阅读过,除非确实需要,否则不应该使用指针。

当您阅读任何建议时,您应该尝试理解为何提供此建议。如果建议背后没有充分的理由,就没有必要遵循这个建议。

试图消除程序中的所有指针只是因为有人告诉你“指针不好”并不是一个好主意。

有经验的程序员告诉你要避免使用原始指针,因为指针意味着手动内存管理,这很容易出错(忘记删除内容==内存泄漏),而且你必须要注意rule of three
我也有这样的印象:经验不足的程序员经常给出相同的建议,因为他们根本不完全理解指针(或者害怕它们?)。

您可以使用引用,但因为您无法复制/重新分配不太有用的引用。例如:

#include <iostream>

class A{
public:
    virtual int getVal() const = 0;
    virtual ~A(){}
};

class B: public A{
public:
    virtual int getVal() const { return 2; };
};

class C: public A{
public:
    virtual int getVal() const { return 3; };
};

class D{
public:
    const A& getInterface(bool which) const{
        if (which)
            return c;
        return b;
    }
protected:
    B b;
    C c;
};

int main(int argc, char** argv){
    D d;
    std::cout << d.getInterface(true).getVal() << std::endl;
    std::cout << d.getInterface(false).getVal() << std::endl;
    return 0;
}

如您所见,要通过引用返回对象,您需要在某处创建它并存储它。如果你想“杀死所有指针”,那么你需要将这个对象创建为更大类的成员变量(或者作为全局变量)。

使用指针,您只需返回shared_ptr<A>

在您的代码中,更好的想法是使用smart pointer类而不是原始指针。这将消除手动删除/内存管理的需要。

  

在不使用Input *

的情况下重写上面的代码是可能的,也是更好的

是的,这是可能的,但是没有理由这样做,这是(IMO)并不是更好。我的例子说明了你如何做到这一点。没有指针(任何类型 - 智能或原始)你还必须在某处存储BOTH CameraInput和VideoInput,而使用指针你可以按需创建它们。

答案 1 :(得分:0)

您可以使用智能指针(例如std :: unique_ptr或std :: shared_ptr)代替原始指针。
如果你想要多态,你必须使用指针或引用。有比你真正想要的更多细节here