2015-05-13 4 views
1

Моя проблема в том, что у меня есть класс под названием «Продукт» и еще один класс под названием «Сельское хозяйство», класс «Сельское хозяйство» наследует класс «Продукт».Инициализация предварительного конструктора

Когда я вызываю конструктор «Сельское хозяйство», очевидно, сначала вызывается конструктор «Продукт».

Вопрос в том, можно ли сначала инициализировать один из элементов продукта с помощью метода набора?

+1

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

+0

Вопрос довольно неясен. Пожалуйста, проясните это с помощью соответствующего примера кодирования (другими словами, ** покажите свой код **). –

+0

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

ответ

3

Если у вас есть:

class Product { ... }; 
class Agriculture : public Product { ...}; 

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

Рекомендация:

Лучший дизайн для ваших потребностей будет предвидеть Product конструктор, который принимает в качестве дополнительного параметра (ов) значение (ы), которые вы хотите установить:

class Product { 
    string origin; 
public: 
    Product() : origin("tbd") { } 
    Product (string withorigin) { ...} 
    void setOrigin (string myorigin) { origin=myorigin; } 
}; 
class Agriculture : public Product { 
public: 
    Agriculture() : Product ("Earth") { ...} 
}; 

Обходное решение:

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

class Product { 
    static string defaultCurrency; 
    string currency; 
public: 
    Product() : currency(defaultCurrency) { ... } 
    static void setDefaultCurrency (string cur) { defaultCurrency=cur; } 
}; 
class Agriculture : public Product { ... }; 

int main() { 
    Product::setDefaultCurrency("EUR"); 
    Agriculture a1; 
} 

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

+0

У меня есть много видов продукции (сельское хозяйство, дневник и т. Д.), И я хочу, чтобы всякий раз, когда я строил тип продукта, например, сельское хозяйство, я хочу, чтобы конструктор продукта работал по-разному для каждого типа, могу ли я хотя бы сделать это ? –

+1

@AssafKaravani сделать два конструктора – user3528438

+1

Я использовал вашу рекомендацию, и это сработало! Большое спасибо! –

1

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

+0

Если вы хотите «Я хочу, чтобы всякий раз, когда я строил тип продукта, например, сельское хозяйство, я хочу, чтобы конструктор продукта работал по-разному для каждого типа», вы можете определить виртуальную функцию в Product, а затем реализовать разные версии для установки значений в каждом производном классе – JackChen255

+0

Примечание: вы можете ** НЕ ** вызывать виртуальные методы во время построения. –

Смежные вопросы