【问题标题】:Convert Object to Pointer to Object?将对象转换为指向对象的指针?
【发布时间】:2018-05-22 16:21:58
【问题描述】:

我在 C++ 中有以下内容:

#ifndef INTERFACE_H
#define INTERFACE_H
class Interface {
public:
        virtual void blah() = 0;
};
#endif

#ifndef USER_H
#define USER_H

#include "Interface.h"
#include <iostream>

class User {
public:
        void callBlah(Interface* ptr) {
                ptr->blah();
        }
};
#endif

我有这个 SWIG 接口文件:

%module(directors="1") interface

%{
#include "Interface.h"
#include "User.h"
%}

%feature("director") Interface;
%include "Interface.h"
%include "User.h"

我编译了:

$ swig -Wall -c++ -python -I/usr/include/python3.6m interface.i 
Interface.h:3: Warning 514: Director base class Interface has no virtual destructor.
$ g++ -shared -fPIC -I/usr/include/python3.6m Foo.cpp interface_wrap.cxx -o _interface.so

然后,我跑了:

import interface

class Implementation(interface.Interface):
    def __init__(self):
            super().__init__()
            self.__something = 1
    def blah(self):
            print("called python version")

i = Implementation().__disown__
u = interface.User()
u.callBlah(i)

它给了:

Traceback (most recent call last):
  File "test.py", line 12, in <module>
    u.callBlah(i)
  File "/home/foo/test/swig/interface.py", line 142, in callBlah
    return _interface.User_callBlah(self, ptr)
TypeError: in method 'User_callBlah', argument 2 of type 'Interface *'

所以主要问题是变量 i 是 Implementation 的对象(它实现了接口)但 User::callBlah() 期望参数是指向接口的指针。

我的问题是如何在不更改 C++ 代码的情况下将 i 转换为指向实现/接口的指针?

谢谢!

【问题讨论】:

  • 这应该“正常工作”,我看不出它为什么不工作。
  • 原来用 i = Implementation() 替换 i = Implementation().__disown__ 可以解决问题。

标签: python c++ python-3.x swig


【解决方案1】:

只要看看你的这部分代码:

#ifndef INTERFACE_H
#define INTERFACE_H
class Interface {
public:
        virtual void blah() = 0;
};
#endif

您有一个具有纯虚方法的类。这意味着您无法创建 如果直接使用接口类型的对象,它将无法编译。这意味着您必须从此类继承,并且从此类继承的所有类都必须实现函数blah()。此外,由于您是从纯虚拟抽象基类继承的,因此您还应该有一个 virtual destructor

你可以这样做:

#ifndef INTERFACE_H
#define INTERFACE_H

class Interface {
public:
    virtual ~Interface();
    virtual void blah() = 0;
};

#endif 

#ifndef INTERFACE_IMPL
#define INTERFACE_IMPL

class InterfaceImpl : public Interface {
public:
    InterfaceImpl() {}
    virtual ~InterfaceImpl(){}

    virtual void blah() override { /* implementation of blah here; */ }
};

#endif

然后任何源代码使用Interface 直接将其替换为InterfaceImpl 或指向Inteface 类型的指针。如果您使用后者,则必须在 basechild 类之间进行一些转换。

【讨论】:

  • 感谢您的回复。是的,我需要实现接口。但是,我想用 Python 而不是 C++ 来实现,我在我的帖子中做了实现类定义。
  • @Hei Ah 好的;我明白,但我还不知道 Python ......所以我的帮助是有限的,只停留在 C++ 部分,但是是的,你需要先修复 C++ 编译器错误。哦,我在函数blah 的第二类定义中对我的帖子进行了编辑,我添加了override 说明符。这在处理纯虚拟类、抽象类和多态时也很有用。
  • 感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2021-07-22
  • 1970-01-01
  • 2014-01-02
  • 1970-01-01
  • 1970-01-01
  • 2011-02-06
  • 1970-01-01
  • 2017-08-16
相关资源
最近更新 更多