Подтвердить что ты не робот

параметры по умолчанию в файлах.h и.cpp.

КОМПЬЮТЕР: g++ 4.7.2

ОК. Поэтому я смущен параметрами по умолчанию в файлах .h и .cpp. Во многих местах (включая этот сайт) упоминается, что параметры по умолчанию могут быть добавлены только в.h файлах, а не в.cpp файлах. Однако этот код доказывает это неправильно:

test1.h

#pragma once

#include <iostream>
using namespace std;

class Class{
public:
    Class(int, int, int=1);
};

test1.cpp

#include "test1.h"

Class::Class(int a, int b=2, int c)
{
    cout<<a<<" "<<b<<" "<<c<<endl;
}

int main()
{
    Class a(1);
    return 0;
}

Теперь, согласно тому, что я тестировал, параметры по умолчанию могут быть добавлены в файлы .cpp. Однако существуют следующие ограничения:

  1. Параметры по умолчанию, присутствующие в файлах .cpp и .h не должны перекрываться. т.е. Class(a, b, c=1) (в.h файле) и Class::Class(a,b,c=2) (в.cpp файле) является недопустимым.

    Хорошо известно, что после добавления параметров по умолчанию все переменные, объявленные после этого, также должны содержать значения по умолчанию. Давайте назовем это правило defpara. Теперь,

  2. Переменные, указанные в объявлении функции (файл .h), должны подчиняться правилу defpara, т.е. Class(a, b=2, c) (в.h файле) является недопустимым, независимо от того, что объявлено в.cpp файле.

  3. Если рассматривать переменные, имеющие значения по умолчанию (как пересечение значений по умолчанию в файлах .h и .cpp), оно будет следовать правилу defpara. т.е. Class(a, b, c=1) (в файле.h) и Class::Class(a,b=2,c) (в файле .cpp) действительны. Но Class(a, b, c=1) (в.h файле) и Class::Class(a=2,b,c).cpp файле) являются недопустимыми.

Итак... Я прав, неправильно???

4b9b3361

Ответ 1

Это работает только потому, что ваша основная функция также находится в вашем файле test.cpp, поэтому он видит аргумент по умолчанию, указанный в реализации вашего класса. Если вы поместите свою main функцию в отдельный файл, который включает только test.h, этот код не будет компилироваться.

Другой способ взглянуть на это - когда некоторые другие включают test.h, все, что видит код, - это то, что объявлено в test.h, поэтому аргументы по умолчанию, помещенные в другое место, не будут использоваться.

Ответ 2

Значения по умолчанию всегда должны находиться в файле заголовка, если функция объявлена в файле заголовка.

Это связано с тем, что компилятор будет использовать заголовочный файл для ВСЕХ компиляторов, которые используют ваш класс [если вы не являетесь "непослушными" и не используете заголовочный файл везде, куда он должен идти].

Поскольку компилятор добавляет аргументы по умолчанию, когда компилирует код, который ВЫЗЫВАЕТ функцию (в данном случае конструктор), не имеет значения, какие значения по умолчанию находятся в файле.cpp.

Конечно, в этом случае есть только один "пользователь" файла заголовка и только одно место, где вызывается конструктор. Но наличие значений по умолчанию в файле.cpp обычно неверно [если это не локальная функция].

Вы получаете очень "интересные" ошибки, если вы "смешиваете" значения по умолчанию - например, если ваш.cpp имеет один по умолчанию, а headefile - другой. Если вы действительно умеете, вы даже можете заставить компилятор генерировать разные значения по умолчанию для разных вызовов функции, что почти наверняка приведет к некоторому сбору в работе, если код полагается на значение по умолчанию определенного значения. И не испытывайте соблазна скопировать значения по умолчанию из заголовка в.cpp файл "просто, чтобы было легче увидеть". Если кто-то изменит значение по умолчанию, то он почти наверняка либо не изменится в обоих местах, а, возможно, и хуже: измените неправильные значения по умолчанию, чтобы он не делал то, что предназначалось.

Ответ 3

.h против.cpp - красная селедка. Правило состоит в том, что аргументы по умолчанию могут использоваться в объявлениях функций и в определении функции. Вам не разрешено переопределять аргумент по умолчанию, даже не до того же значения. Так что это не законно:

void f(int, int = 3);
void f(int, int = 3); // error: redefinition of default argument

Однако последующие объявления могут добавлять аргументы по умолчанию:

void f(int, int = 3);
void f(int = 4, int = 3);
f(); // calls f(4, 3);

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

void f(int, int =3);
f(1); // calls f(1, 3);
void f(int = 4, int = 3);
f(1); // calls f(1, 3);
f();  // calls f(4, 3);

В исходном примере файл.h определяет один аргумент по умолчанию, и любая единица перевода, которая использует этот заголовок, может использовать этот аргумент по умолчанию:

Class c3(1, 2, 3);
Class c2(1, 2);

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

Class c3(1, 2, 3);
class c2(1, 2);
class c1(1);

Ответ 4

Не существует такого параметра, как параметр по умолчанию для определения файла в C++ - он существует только в объявлении.

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

PS: Пункт 38/Scott Myers/Effective C++ - Никогда не переопределяйте унаследованное значение параметра по умолчанию.