Что делать, если значение параметра по умолчанию определено в коде, который не отображается на сайте вызова?

Я нашел какой-то странный код...

//in file ClassA.h:
class ClassA {
public:
    void Enable( bool enable );
};

//in file ClassA.cpp
#include <ClassA.h>
void ClassA::Enable( bool enable = true )
{
   //implementation is irrelevant
}

//in Consumer.cpp
#include <ClassA.h>
....
ClassA classA;
classA.Enable( true );

Очевидно, что поскольку Consumer.cpp включен только ClassA.h, а не ClassA.cpp, компилятор не сможет увидеть, что параметр имеет значение по умолчанию.

Когда будет объявлено объявленное значение по умолчанию ClassA::Enable в сигнатуре реализации метода? Это произойдет только тогда, когда метод вызывается из файлов, содержащих ClassA.cpp?

Ответ 1

Значения по умолчанию - это всего лишь время компиляции. В компилируемом коде нет такой вещи, как значение по умолчанию (без метаданных или подобных вещей). Это в основном замена компилятора для "если вы ничего не пишете, я укажу это для вас". Итак, если компилятор не видит значения по умолчанию, он не предполагает, чтобы он не был.

Демо:

// test.h
class Test { public: int testing(int input); };

// main.cpp
#include <iostream>
// removing the default value here will cause an error in the call in `main`:
class Test { public: int testing(int input = 42); };
int f();
int main() {
   Test t;
   std::cout << t.testing()  // 42
             << " " << f()   // 1000
             << std::endl;
   return 0;
}

// test.cpp
#include "test.h"
int Test::testing(int input = 1000) { return input; }
int f() { Test t; return t.testing(); }

Тест:

g++ main.cpp test.cpp
./a.out

Ответ 2

Позвольте мне сначала признать, что это первый раз, когда я видел этот тип кода. Поставить значение по умолчанию в файл заголовка IS обычную практику, но это не так.

Я предполагаю, что это значение по умолчанию может использоваться только из кода, написанного в том же файле, и таким образом программист, который написал это, захотел поместить его в некоторую легкость при вызове функции, но он не хотел беспокоить интерфейс (файл заголовка), видимый внешнему миру.

Ответ 3

Поместите значение по умолчанию в объявление, а не в определение.

class ClassA {
public:
    void Enable( bool enable = true );
};

Ответ 4

Это произойдет только тогда, когда метод вызывается изнутри файлов, которые включить ClassA.cpp?

Это правильно. Но обратите внимание, что при этом почти наверняка будут возникать множественные ошибки определения, поэтому значение по умолчанию доступно только с точки определения в ClassA.cpp.