2015-08-23 6 views
2

Недавно я заинтересовался изучением языка программирования D. (В частности, D2, который на момент написания - это то, к чему люди относятся, как D, теперь находится в режиме обслуживания для совместимости с существующим кодом.)Есть ли что-нибудь, что C++ может сделать лучше, чем D, или что D не может сделать? (пример множественного наследования)

Прежде чем я решит, использовать ли C++ или D (я уже знаю C++, я ничего не знаю о D), я хочу знать, есть ли что-то, что C++ лучше, чем D? Если вы читаете о D онлайн, есть много материала, который просто говорит: «Вот пример кода на C++, вот пример этого кода в D и посмотрите - это бывает намного лучше». Что, конечно, верно для показанных примеров.

Некоторые из различий могут подлежать рассмотрению. Например, вызов конструктора базового класса из производного класса выполняется с помощью super() (D), а не <class name>(args) в списке инициализации (после : нотации.) (C++). Лично мне это не нравится super, но это только мое мнение, и это не вопрос, который я задаю.

Более уместно то, что D не может поддерживать множественное наследование. (!)

  • Что еще НЕ поддерживает то, что делает C++?
  • Есть ли примеры того, что C++ делает лучше в D для некоторой синтаксической или логической причины? (Не в первую очередь основанное на мнениях, но не стесняйтесь отвечать аргументом, основанным на мнениях, если это актуально и конструктивно.)
  • Означает ли факт, что D не поддерживает множественные наследования, приводит к ситуациям, когда вы «заперты» от выполнения что вы могли бы сделать на C++? (Я думаю, может быть, iostream/ifstream/ofstream операции?)
  • Есть ли способы вокруг множественного запрета наследования, если вам это действительно нужно?

Например, одна вещь, которую вы можете сделать в C++ есть что-то вроде следующего:

class base 
{ 

} 

class base_has_read_operation 
{ 
    public: 
    void read() 
    { 
     // complicated read function, 100000 lines of code... 
    } 

    virtual void do_read() = 0; 

    private; 
    // data 
} 

class base_has_write_operation 
{ 
    public: 
    void write() 
    { 
     // complicated write function, 100000 lines of code 
    } 

    virtual void do_write() = 0; 

    private: 
    // data 
} 

class reader : public base_has_read_operation 
{ 
    public: 
    void do_read() 
    { 
     read(); 
    } 
} 

class writer : public base_has_write_operation 
{ 
    public: 
    void do_write() 
    { 
     write(); 
    } 
} 

class read_writer : public base_has_read_operation, base_has_write_operation 
{ 
    public: 
    void do_read() 
    { 
     read(); 
    } 

    void do_write() 
    { 
     write(); 
    } 
} 

Но предположительно без множественного наследования вы не можете сделать это?

+0

Это интересно, но это кажется слишком открытым для этого сайта. – Potatoswatter

+3

См. Здесь: http://programmers.stackexchange.com/questions/97207/what-does-c-do-better-than-d –

+0

Добро пожаловать в Тьюринга Трет Пит, где все эквивалентно, но ничего интересного , Вы можете реализовать D в C++ и наоборот: ни один из них не может сделать то, что другой не может. – Yakk

ответ

4

Проблема с несколькими наследствами может быть решена с использованием шаблона mixin, в другом слове - фрагмент кода, который помещен в другой. Пример:

interface IWriter { 
    void do_write(); 
} 

// It is a template, you can specify compile-time arguments 
mixin template Write() { 
    // complicated write function 
} 

interface IReader { 
    void do_read(); 
} 

mixin template Read() { 
    // complicated read function 
} 

// D has multiple interface inheritance 
class ReaderWriter : IWriter, IReader { 
    void do_write { 
         // You can do other things before... 
     mixin Write; // The code of Write is inserted here 
         // ...or after 
    } 

    void do_read { 
     mixin Read; 
    } 
} 

я мог бы утверждать, что, хотя вы, конечно, было бы лучше, если бы ваш ReaderWriter имел ручку для читателя и писателя, вместо того, чтобы полагаться на более-соединения множественного наследования.

1

Я переехал с C++ на D два месяца назад, поэтому, возможно, я ошибаюсь. Квалификатор ref не заменяет ссылки на C++. В частности, с ссылками и пересылкой ссылок на C++ 11 вы можете делать большую эффективность, например, только при копировании параметра, если это необходимо. Один из аспектов D, с которым я столкнулся, - это ссылочные и стоимостные типы. C++ настолько прозрачен для этого. Это затрудняет запись эффективного кода. Предположим, у вас есть класс C!(T). Возможно, вы захотите создать T, но если T - это класс, вам необходимо T t = new T(arg) иначе T t = T(arg). Я использовал mixin и как T t = mixin((is (T == class) ? "new " : "") ~ "T(arg)");. Это довольно уродливо. В этом случае я бы предпочел объекты значения C++.

+0

Я думаю, что общий код, который иногда выделяет новый объект, а иногда и не является ошибкой так или иначе, поскольку у него есть потенциально скрытая стоимость ... но вы можете получить подобное поведение в любом случае с 'auto t = new T (arg);', который работает со всеми типами (включая, я думаю, встроенные ins, такие как int ...). Это будет постоянно давать ссылочный тип. –

+0

Теперь мне приходится иметь дело с указателями; это точно * не * вещь, которую я хочу. Я всегда хочу одного и того же типа в зависимости от '' T'', предпочтительно '' T''. Не может ли это быть по-другому? – Bolpat

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

  • Нет связанных вопросов^_^