Создание нескольких копий с использованием перегруженного оператора ‘*’

#c #constructor #copy-constructor

#c #конструктор #конструктор копирования

Вопрос:

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

Тоесть.

 myclass instance;
instance * 5;
  

создало бы 5 копий экземпляра. Итак, я использую массив объектов для создания этих экземпляров.

 cube* operator* (int i, const cubeamp; thing) {
        cube* objectarr = new cube[i];
        for (int j = 0; j < i; j  ) {
            objectarr[i] = thing;
        }
        std::cout << i << " number of copies createdn";
        return objectarr;
    }
  

Но я получаю сообщение об ошибке «слишком много параметров для этой функции».
Однако, если я сделаю это дружественной функцией, то она может принимать более одного аргумента.
Проблема возникает, когда я пытаюсь выполнить пример.

 #include <iostream>

#define TB 't'
struct cube {
    int height;
    int width;
    int bredth;
    cube() {
        height = 0;
        width = 0;
        bredth = 0;
    }
    cube(int i, int j, int k) {
        height = i;
        width = j;
        bredth = k;
    }
    cube operator =(const cubeamp; c);
    friend cube* operator* (int i, const cubeamp; thing) {
        cube* objectarr = new cube[i];
        for (int j = 0; j < i; j  ) {
            objectarr[i] = thing;
        }

        std::cout << i << " number of copies createdn";
        return objectarr;
    }
};

int main() {
    cube c1(10, 20, 30);
    cube* mptr = new cube;
    mptr = 4 * c1;
    for (int i = 0; i < 4; i  ) {
        std::cout << mptr[i].height << TB << mptr[i].width << TB << mptr[i].bredth << std::endl;
    }
    return 0;
}
  

Результат приведенного выше кода таков.

 4 number of copies created
0       0       0
0       0       0
0       0       0
0       0       0
  

Я хочу знать

1. Почему это происходит?

2. Почему оператор умножения не может принимать более одного аргумента, за исключением случаев, когда это дружественная функция (я искал ее в Интернете, но мало что понял)?

Спасибо

Комментарии:

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

2. Также cube * mptr = new cube; mptr = 4 * c1; не собирается делать то, что он делает — я думаю, вам следует рассмотреть возможность использования интеллектуальных указателей векторы.

3. @UKMonkey ` Также cube* mptr = новый куб; mptr = 4 * c1; не собирается делать то, что вы хотите, чтобы он делал ` , почему?

4. mptr = новый куб: выделяет память и вызывает конструктор по умолчанию; mptr = XXX : утечка памяти

Ответ №1:

  1. это злоупотребление оператором, просто используйте конструктор копирования.
  2. instance * 5 это не то же самое, что 5 * instance . У вас есть последнее.

Комментарии:

1. В определении int предшествует object , friend cube* operator* (int i, const cubeamp; thing); и в main() тоже я использую 4 * c1 , не c1 * 4

Ответ №2:

Боюсь, ничего не получится.

Вам не разрешается изменять arity оператора при его перегрузке. Это означает, что вы не можете настроить количество аргументов.

friend Функция, на которую вы ссылаетесь, будет относиться к версии перегруженного оператора умножения для вашего конкретного класса в области видимости «вне класса»: поэтому она будет принимать 2 аргумента.

Ответ №3:

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

Оператор ‘*’ не предназначен для этого.

Ответ №4:

Если перегрузка является элементом, *this это левая сторона оператора и есть только один явный параметр.
Если вы хотите, чтобы левый аргумент был чем-то другим, а не вашим классом, вы должны сделать перегрузку свободной функцией.

Например, если у вас есть

 struct A
{
     int operator *(int x) { return x * y; } 
     int y;
};

int operator*(int x, A a) { return a.y * x }


A a{2};
  

затем

 int z = a * 2; 
  

вызывает a.operator*(2) , в то время как

 int w = 2 * a;
  

вызовы operator*(2, a) .

Лучшей реализацией вашего конкретного оператора было бы

 std::vector<cube> operator* (int i, const cubeamp; thing) 
{
    return std::vector<cube>(i, thing);
}
  

или, если вы хотите симметрии:

 struct cube
{
   // ...
   std::vector<cube> operator*(int i) const { return std::vector<cube>(i, *this); }
};

std::vector<cube> operator* (int i, const cubeamp; thing) 
{
    return thing * i;
}