Во-первых, тег [c]
неуместен, поскольку конструкторы доступны только для C ++. Я предполагаю, что предоставленный вами фрагмент кода на самом деле - C ++, а не какой-то странный диалект языка C. C ++ и C - это разные языки ; не помечайте свои вопросы как оба, так как вы получите разные ответы для каждого.
Во-вторых, ваше определение конструктора неверно. Конструкторы должны иметь то же имя, что и сам класс. Так что f()
должно было быть F()
. Да, чувствительность к регистру имеет значение в C ++! Я предполагаю, что это то, что вы имели в виду для остального фрагмента кода. OP просто сделал опечатку.
Прежде чем объяснить, что делает остальная часть вашего кода, вы должны понимать, что все классы (и структуры) в C ++ имеют специальные функции-члены , которые автоматически генерируются компилятором, если вы их не предоставляете , То есть ваш фрагмент кода в основном такой же, как:
struct F
{
F(int _a, int _b) {a = _a; b = _b}; // constructor
~F() {} // destructor
F(const F& rhs) // copy constructor
: a(rhs.a)
, b(rhs.b)
, c(rhs.c)
, d(rhs.d)
{}
F& operator=(const F& a) // copy assignment operator
{
a = rhs.a;
b = rhs.b;
c = rhs.c;
d = rhs.d;
return *this;
}
void a(int _a, int _b) {a = _a; b = _b}; // one of your functions
int a;
int b;
int c;
int d;
};
Если вы не определили конструктор копирования, оператор назначения копирования или деструктор, компилятор сгенерирует их для вас. Кроме того, если вы не предоставите какой-либо другой конструктор, компилятор сгенерирует конструктор по умолчанию. Для класса F
не существует конструктора по умолчанию, поскольку уже существует конструктор (не для копирования), который принимает два аргумента.
Реализация по умолчанию конструктора копирования и оператора назначения копирования просто копирует каждый элемент данных.
Причина, по которой существуют специальные функции-члены, заключается в том, что C ++ обобщает понятие копирования примитивных типов в определенные пользователем объекты. Учтите это:
int a = 42;
int b = 13;
b = a;
С такими примитивными типами, как int
s, вы можете просто копировать его значение. C ++ обобщает семантику копирования для объектов, так что вы можете сделать это:
F f(10, 20); // calls first constructor
F g(30, 40); // calls first constructor
g = f; // calls g's copy-assignment operator.
Теперь вы можете увидеть, как это относится к вашему коду:
F f = F(5,6);
Строка выше создает временный объект F
, а затем копирует временный объект в f
через конструктор копирования. Временный объект F
затем уничтожается.
f = F(7,8);
В приведенной выше строке создается другой временный объект F
, а затем назначается временный объект в f
с помощью оператора копирования. Временный объект F
затем уничтожается. Исходный f
объект не разрушен.
f.a(9,0)
Строка выше - это обычный вызов функции для объекта с именем f
.
Для вашего фрагмента кода, если предположить, что компиляторы не оптимизируют временные значения (они обычно это делают), то вызов функции a
является "менее ресурсоемким", поскольку в этом случае временные действия не производятся. Однако для вашего первого вызова конструктора вы можете просто сделать это:
F f(5,6); // Constructor called; no temporaries are made
Понять, для чего используются конструкторы: они используются для создания объектов . Если у вас уже есть объект, вам не нужно вызывать конструктор.
Как я много раз рекомендовал, пожалуйста, возьмите хорошую книгу по C ++ и прочитайте ее. Специальные функции-члены и то, что они делают, являются фундаментальными для C ++.