为什么编译器会尝试在此代码段中传递指向引用而不是指针的指针?

时间:2012-04-11 05:43:02

标签: c++ inheritance pointers virtual pass-by-reference

我有5个文件:

  • ExecutionStrategyInterface.h
  • ExecutorInterface.h
  • TaskCollectionInterface.h
  • TaskExecutor.h
  • TaskExecutor.cpp

TaskExecutor实现以下成员方法:

void TaskExecutor::execute(TaskCollectionInterface* tci, const ExecutionStrategyInterface& es) {
    es.execute(tci);
}

在编译时,编译器调用一个成员方法,该方法的参数类型为指向引用的指针(即:mylib::core::TaskCollectionInterface*&)。

TaskExecutor.cpp: In member function ‘virtual void mylib::core::TaskExecutor::execute(mylib::core::TaskCollectionInterface*, const mylib::core::ExecutionStrategyInterface&)’:
TaskExecutor.cpp:16: error: no matching function for call to ‘mylib::core::ExecutionStrategyInterface::execute(mylib::core::TaskCollectionInterface*&) const’
./././ExecutionStrategyInterface.h:24: note: candidates are: virtual void mylib::core::ExecutionStrategyInterface::execute(TaskCollectionInterface*) const
make: *** [TaskExecutor.o] Error 1

有人能解释一下这里发生了什么吗?


类:

ExecutionStrategyInterface.h

#ifndef _EXECUTIONSTRATEGYINTERFACE_H_
#define _EXECUTIONSTRATEGYINTERFACE_H_

class TaskCollectionInterface;

namespace mylib { namespace core {

/**
 *  Interface for executing a strategy.
 */
class ExecutionStrategyInterface {
 public:
    /**
     * Executes a strategy
     */
    virtual void execute(TaskCollectionInterface* tci) const = 0;
};

}} // namespaces

#endif // _EXECUTIONSTRATEGYINTERFACE_H_

TaskCollectionInterface.h

#ifndef _TASKCOLLECTIONINTERFACE_H_
#define _TASKCOLLECTIONINTERFACE_H_

#include "./ExecutionStrategyInterface.h"

namespace mylib { namespace core {

/**
 *  Interface for a collection of tasks.
 */
class TaskCollectionInterface {
 public:
    ~TaskCollectionInterface();
};

}} // namespaces

#endif // _TASKCOLLECTIONINTERFACE_H_

ExecutorInterface.h

#ifndef _EXECUTORINTERFACE_H_
#define _EXECUTORINTERFACE_H_

class ExecutionStrategyInterface;
class TaskCollectionInterface;

#include "./ExecutionStrategyInterface.h"
#include "./TaskCollectionInterface.h"

namespace mylib { namespace core {

/**
 *  Interface for an executor.
 */
class ExecutorInterface {
 public:
    virtual void execute(TaskCollectionInterface* tci, const ExecutionStrategyInterface& es) = 0;
    ~ExecutorInterface();
};

}} // namespaces

#endif // _EXECUTORINTERFACE_H_

TaskExecutor.h

#ifndef _TASKEXECUTOR_H_
#define _TASKEXECUTOR_H_

#include "./ExecutorInterface.h"

class TaskCollectionInterface;
class ExecutionStrategyInterface;

namespace mylib { namespace core {

/**
 *  Task Runner.
 */
class TaskExecutor: public ExecutorInterface {
 public:
    virtual void execute(TaskCollectionInterface* tci, const ExecutionStrategyInterface& es) = 0;
};

}} // namespaces

#endif // _TASKEXECUTOR_H_

TaskExecutor.cpp

#include "./TaskExecutor.h"
#include "./ExecutionStrategyInterface.h"
#include "./TaskCollectionInterface.h"

namespace mylib { namespace core {

void TaskExecutor::execute(TaskCollectionInterface* tci, const ExecutionStrategyInterface& es) {
    es.execute(tci);
}

}} // namespaces

3 个答案:

答案 0 :(得分:2)

这是令人困惑的,因为你是在命名空间之外向前声明类,所以你最终会得到两个具有相同名称的不同类。你会想要这样的东西:

namespace mylib {
  namespace core {
    class TaskCollectionInterface;
    class ExecutionStrategyInterface {
      .
      .
      .
    };
  }
}

现在你的方式,你的execute方法是指向:: TaskCollectionInterface而不是mylib :: core :: TaskCollectionInterface。

答案 1 :(得分:0)

当gcc说type&时,它只是表示你传递一个左值的速记,这样你就知道采用非常量引用的函数是可行的候选者。

您遇到的问题是您已将该方法声明为::TaskCollectionInterface,但错误消息表明您正在尝试传递::mylib::core::TaskCollectionInterface

::mylib::core::TaskCollectionInterface中的TaskCollectionInterface.h声明掩盖了命名空间::TaskCollectionInterfacemylib::core的声明。

答案 2 :(得分:-1)

这是因为您将指针TaskCollectionInterface* tci传递给ExecutionStrategyInterface::execute方法,而它需要引用。因此,在将指针传递给该函数时,必须取消引用该指针:

void TaskExecutor::execute(TaskCollectionInterface* tci, const ExecutionStrategyInterface& es) {
    es.execute(*tci);
}