Существует ли __новый__ эквивалент для C ?

#c #new-operator

Вопрос:

__new__ Переопределение в Python позволяет создавать объект совершенно другого класса, используя конструктор одного класса. Было интересно, есть ли какой-либо способ добиться этого на C или любом другом языке, если на то пошло? Написание определенного программного обеспечения для решения задач, первоначально на Python, затем перешло на Java по соображениям скорости, а также ясности структуры, и имело псевдо-способ достижения этой цели для Java, но поскольку C более гибкий и универсальный, возможно, реальная вещь может быть возможной. Спасибо за внимание

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

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

2. В любом случае избегайте любых новых/удаляемых в C в настоящее время.

3. Я не уверен, что переход на Java с Python по соображениям производительности является разумным.

4. @nada: Многопоточный дизайн Java значительно опережает Python. Это буквально так хорошо, что C прямо украл свою потоковую модель еще в 2003 году.

Ответ №1:

Память для объекта выделяется до вызова конструктора.

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

Вместо этого используйте заводскую функцию.

Ответ №2:

Буквальный перевод того, что вы хотите сделать, вероятно, будет выглядеть так:

 class A {};
class B {};
class C {};

void* create_object(char class_letter) {
    switch (class_letter) {
        case 'A': return new A;
        case 'B': return new B;
        case 'C': return new C;
        default: return new A;
    }
}
 

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

 void* ptr = create_object('B');
 

Вы получаете void* то, что не очень приятно иметь, потому что теперь ваша обязанность привести его к правильному типу, например, выполнив:

 B* b_ptr = (B*)ptr; // eww!
 

и не менее важно — теперь это также ваш долг перед delete ним (фу!), что является популярной вещью, о которой мы, программисты, склонны забывать.


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

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

1. Не понял твоей точки зрения. Вы показали небезопасный дизайн, а затем сказали, что он плохой. Эта же схема может быть реализована с общим базовым классом std::unique_ptr и dynamic_cast / или с шаблонами без каких-либо проблем.

2. @sklott, конечно. Вы можете расширить мой ответ, если вам так хочется. Просто хотел, чтобы все было просто и просто. Есть также std::variant и, вероятно, многое другое, что может быть полезно для OP. C — это мощный инструмент.