Google Mock: «нет подходящего конструктора по умолчанию»? - PullRequest
6 голосов
/ 06 июля 2011

Использование Visual Studio 2010 C ++ с googlemock. Я пытаюсь использовать макет, который я создал, и я получаю сообщение об ошибке компилятора в строке:

EmployeeFake employeeStub;

Ошибка:

1>c:\someclasstests.cpp(22): error C2512: 'MyNamespace::EmployeeFake' : no appropriate
default constructor available

EmployeeFake:

class EmployeeFake: public Employee{
 public:
  MOCK_CONST_METHOD0(GetSalary,
      double());
}

Сотрудник:

class Employee 
{
public:
    Employee(PensionPlan *pensionPlan, const char * fullName);
    virtual ~Employee(void);

    virtual double GetSalary() const;
}

Я понимаю, что проблема в том, что базовый класс не имеет конструктора по умолчанию, но как мне это исправить? Нужно ли добавлять конструктор по умолчанию в мой базовый класс? Или мне нужно добавить конструктор в мой фиктивный класс? Или что-то еще?

Ответы [ 2 ]

9 голосов
/ 06 июля 2011

Вы можете просто добавить в макет конструктор, который делегирует конструктору Employee:

 class MockEmployee : public Employee {
     public:
         MockEmployee(PensionPlan* pension_plan, const char* full_name)
         : Employee(pension_plan, full_name) {}
         // ...
 };

Затем создайте MockEmployee, как если бы вы создавали Employee. Однако есть несколько вещей, которые можно улучшить в этом коде, которые я очень рекомендую, и это упростит это:

  1. Сделать Employee чисто виртуальным (с защищенным конструктором по умолчанию).
  2. Переименуйте текущую реализацию Employee в имя, описывающее тип сотрудника (например, FullTimeEmployee или EmployeeWithPensionPlan), и сделайте так, чтобы оно наследовало от чисто виртуального типа.
  3. Использовать «virtual ~ Employee ()» вместо «virtual ~ Employee (void)» (явное использование void в параметре является задержкой для C и, насколько я знаю, не в моде в большинстве сообществ C ++). ).
  4. Используйте «const string &» вместо «const char *» для имени.

Итак, чтобы уточнить, моя рекомендация будет:

class Employee {
    public:
        virtual ~Employee() {}
        virtual double GetSalary() const = 0;
    protected:
        Employee() {}
};

class FullTimeEmployee : public Employee {
     // your concrete implementation goes here
};

class MockEmployee : public Employee {
    public:
        MockEmployee() {}
        virtual ~MockEmployee() {}
        // ... your mock method goes here ...
};
2 голосов
/ 06 июля 2011

Вы уже предложили возможный ответ, но давайте обсудим некоторые варианты:

1) Сделать базу по умолчанию конструируемой. Проще всего это сделать, предоставив аргументы по умолчанию:

explicit Employee(PensionPlan *pensionPlan = 0, const char * fullName = "");

(Обратите внимание, что мы говорим explicit, чтобы избежать молчаливых преобразований из PensionPlan*.)

2) Вызвать конструктор в базовом списке инициализатора конструктора производного класса:

EmployeeFake::EmployeFake() : Employee(0, "") { }

2a) Дайте EmployeeFake соответствующий конструктор и передайте его:

EmployeeFake::EmployeeFake(PensionPlan *p) : Employee(p, "[fake]") { } 

(Обратите внимание, что (1) является декларацией, а (2) и (2a) являются определениями.)

...