Можно ли вызвать конструктора класса инстанцированного объекта explicity в C++?

Это поведение make. make расширит рецепты цели перед ее выполнением.

Рецепт $(eval NEW_VER:=$(shell cat version | cut -d '_' -f 2 )) будет расширен, а переменная NEW_VER будет сохранена в списке переменных со значением V7.1.2.3 (из файла версии). Поскольку версия еще не обновлена ​​в файле версии. Рецепт echo $(NEW_VER) будет заменен на echo V7.1.2.3.

Перед выполнением рецепты цели firmware будут

cat version
sed -i 's/V7/V177/g' version
cat version
echo V7.1.2.3

Следовательно, в конце выводится печать старой версии.

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

Makefile:

all: replace_version read_version

replace_version:
    cat version
    sed -i 's/V7/V177/g' version

read_version:
    cat version
    $(eval NEW_VER:=$(shell cat version | cut -d '_' -f 2 ))
    echo $(NEW_VER)

Существует другой возможный способ заставить эту работу работать с одной целью. Измените команду sed как расширяемый рецепт

Makefile:

firmware:
        $(call version_replace, 100)

image.mk

[113 ]
9
задан warren 24 November 2008 в 11:16
поделиться

7 ответов

Можно использовать новое размещение, который разрешает

new (&instance) A(2);

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

A instance(2);

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

15
ответ дан 4 December 2019 в 07:05
поделиться

Нет.

Создайте метод для набора и назовите его от конструктора. Этот метод затем также на потом будет доступен.

class A{
    A(int a) { Set(a); }
    void Set(int a) { }
}

A instance;

instance.Set(2);

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

10
ответ дан 4 December 2019 в 07:05
поделиться

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

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

instance.~A();

Кроме того, placement new может иметь нерасположенный эффект на Вашу память, потому что перегрузки могли бы ожидать, что память, это передается, принадлежит "куче"! В заключении: не делать. сделать. это.

РЕДАКТИРОВАНИЕ, Чтобы продемонстрировать, что вызов деструктора действительно необходим (для не-POD), рассмотрите следующий пример кода:

#include <iostream>

struct A {
    A(int a) { std::cerr << "cons " << a << std::endl; }
    ~A() { std::cerr << "dest" << std::endl; }
};

int main() {
    A instance(2);
    new (&instance) A(3);
}

Как ожидалось программа приводит к следующему выводу:

cons 2
cons 3
dest

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

1
ответ дан 4 December 2019 в 07:05
поделиться

Я вполне уверен, Вы не можете сделать этого. Это - самое главное, конструктор ЯВЛЯЕТСЯ созданием экземпляра класса.

Если конструктора не вызывают вообще или вызывают дважды - какие последствия это могло иметь?

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

3
ответ дан 4 December 2019 в 07:05
поделиться

Нет

Calling instance.A() or A(1) is seens as casting  'function-style cast' : illegal as right side of '.' operator

Обычно, если функция/функциональность к необходимому в конструкторе, а также после того, как объект является construted, это помещается в init () метод и используется в конструкторе и в другом месте также.

пример:

 class A{
      A(int a)
       { 
        init(a);
       }

     void init(int a) { } 
     }

        A instance;

        instance.init(2);
4
ответ дан 4 December 2019 в 07:05
поделиться

Нет Вы не можете сделать этого. Единственный способ вызвать конструктора "новым" ключевым словом.

0
ответ дан 4 December 2019 в 07:05
поделиться

Только для суммирования эти три способа указать явного конструктора через

  1. Экземпляр (2);//делает экземпляр = 2; когда-нибудь работа?

  2. *экземпляр = новый (2);//никогда уверенный в и по сравнению с * здесь, самостоятельно

  3. новый (&instance) (2);

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

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

Случаи исключения: существуют вещи, которые Вы не могли бы иметь в операции конструктора, если для них возможно перестать работать, если не уместно выдать исключение от конструктора. И некоторые люди как наличие "пустых" экземпляров, которые являются propogated использование последующих методов и даже подвергнутых инициализации участников. Интересно исследовать способы смягчить такие ситуации и иметь устойчивые экземпляры, которые не имеют плохих состояний, которые должны быть защищены от в реализациях метода и в использовании.

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

+4. *экземпляр = MakeAnA (2);

+5. *экземпляр = InterestingClass. (2);

-1
ответ дан 4 December 2019 в 07:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: