Различные аргументы в конструкторе класса в C ++ - PullRequest
1 голос
/ 24 февраля 2009

Можно ли заставить конструктор работать по-разному, если аргумент другого типа? то есть int или float.

Допустим, если я это сделаю, новый объект (3) конструктор заполняет массив тремя по каждому индексу

Допустим, если я это сделаю, новый объект (3.5) конструктор заполняет массив индексом + 3,5 для каждого индекса

Допустим, что если я это сделаю, новый Object () конструктор заполняет массив 0.0 по каждому индексу

Есть ли способ достичь этого только одним конструктором? Или мне нужны три разных конструктора?

Спасибо.

Ответы [ 12 ]

6 голосов
/ 24 февраля 2009

Конечно, у вас может быть много конструкторов! Перегрузка для конструкторов работает так же, как и для любой функции / члена.

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

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

3 голосов
/ 24 февраля 2009

Вы можете сделать это с одним конструктором, но это будет ужасно чертовски. Предлагается подход с тремя конструкторами, поскольку он разделяет использование и упрощает код.

2 голосов
/ 24 февраля 2009

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

class Object
{
public:
    // Sets all elements to 0.
    Object();

    // Sets all elements to value.
    static Object Fill(double value);

    // Sets all elements to the previous + delta, beginning at start.
    static Object Accumulate(double start, double delta);
};
1 голос
/ 24 февраля 2009

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

Сказав, что, чисто как упражнение по программированию, это можно сделать с помощью одного конструктора, но вам придется использовать прокси-класс с неявным преобразованием из типов, которые будут различаться для достижения того, что вы хотите. Как готовое решение, boost :: option будет соответствовать требованию. Возможно, вы не считаете, что это соответствует требованиям одного конструктора, поскольку он опирается на несколько конструкторов (или шаблон конструктора) второго класса.

class Object
{
public:
        Object( const boost::variant< int, double >& val = 0 )
        {
                switch( val.which() )
                {
                case 0:
                        // TODO: Fill array with val
                        break;
                case 1:
                        // TODO: fill array with val + index
                        break;
                }
        }

// TODO: Add array member
};
1 голос
/ 24 февраля 2009

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

Кажется, что наиболее очевидным решением этого является вставка оператора switch в ваш конструктор объекта.

Пример:

public Object(int num)
{
switch (num)
{
case 1: array[i]  = num;
break
case 2: array[i] = num * 2;
}

}
1 голос
/ 24 февраля 2009

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

struct Object
{
    Object(double value = 0.0)
    {
        // do that thing you do
    }
};
0 голосов
/ 24 февраля 2009

Используйте 3 разных конструктора, так как логика отличается в зависимости от типа параметра. Кроме того, помните о продвижении типов, выполняемых компилятором. В противном случае вы можете столкнуться с неожиданностями при выполнении кода.

0 голосов
/ 24 февраля 2009

Вы можете учитывать поведение Object() и Object(3), потому что они делают то же самое. Просто напишите свой конструктор так:

class Object {
    // fills an array with n at every index
    Object(int n = 0) { ... }
};

Проблема в том, что конструктор с плавающей точкой (в примере 3.5) имеет , который должен быть отделен, как это:

class Object {
    // fills an array with n at every index
    Object(int n = 0) { ... } // handles Object() AND Object(3)

    // fills an array with index + n at every index
    Object(float n)   { ... } // handles Object(3.5)
};
0 голосов
/ 24 февраля 2009

Нет, вам нужны только три разных конструктора, вам нужны три разных конструктора. Это сделает код чище и проще для понимания, обслуживания и модульного тестирования.

0 голосов
/ 24 февраля 2009

Вам понадобятся либо три разных конструктора (перегружающие их), либо один с некоторыми атрибутами со значениями по умолчанию.

Этого можно достичь, однако я бы предложил использовать 3 разных конструктора для ясности кода и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...