Re: сократить запись
От: uzhas Ниоткуда  
Дата: 20.05.16 13:50
Оценка: 2 (1) +2
Здравствуйте, sci_reseacher, Вы писали:

_>Как сократить запись и избавиться от копирования?


так сойдет?
http://ideone.com/IpuQdh
Re[3]: сократить запись
От: VTT http://vtt.to
Дата: 20.05.16 14:41
Оценка: +1
Так у вас и B и С одинаково наследуют A и D.
Введите промежуточный класс, наследующий от A и D (или D сделать наследником A).
Наследуйте B и C от этого промежуточного класса.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re[3]: сократить запись
От: B0FEE664  
Дата: 20.05.16 14:52
Оценка: :)
Здравствуйте, sci_reseacher, Вы писали:

_>ну попробуйте.

_>у a нет f(), g(), e(), ... .

Это какие-то мелочи и существует сотни способов...
Ну, например:
#include <iostream>
struct A {};
struct D { virtual void f()=0; /* g, e, ...*/ };
struct B: public A,public D { void f(){}; /* g, e, ...*/ };
struct C: public A,public D { void f(){};/* g, e, ...*/ };
    
int main() {

  bool isC = true;

  D* p;
  A* a = isC ? [&p]()->A*{auto pB = new B; p = pB; return pB;}() : [&p]()->A*{auto pC = new C; p = pC; return pC; }();

  p->f();

  return 0;
}
И каждый день — без права на ошибку...
сократить запись
От: sci_reseacher  
Дата: 20.05.16 13:40
Оценка:
Как сократить запись и избавиться от копирования?
struct A {};
struct D { virtual void f()=0; /* g, e, ...*/ };
struct B: public A,D { void f(){}; /* g, e, ...*/ };
struct C: public A,D { void f(){};/* g, e, ...*/ };
    
bool isC = true;

A *a ;    

if( !isC ){
        
  B *b = new B;
  b->f();
  // g()
  // e()
  // ...
  a = b;
        
}else{
        
   C *c = new C;        
   c->f();
   // g()
   // e()
   // ...
   a = c;
    
}


Вот это хотелось бы довести до рабочего состояния:
    
auto x = isC ? new C: new B;
Re: сократить запись
От: B0FEE664  
Дата: 20.05.16 13:51
Оценка:
Здравствуйте, sci_reseacher, Вы писали:

  Скрытый текст
_>Как сократить запись и избавиться от копирования?
_>
_>struct A {};
_>struct D { virtual void f()=0; /* g, e, ...*/ };
_>struct B: public A,D { void f(){}; /* g, e, ...*/ };
_>struct C: public A,D { void f(){};/* g, e, ...*/ };
    
_>bool isC = true;

_>A *a ;    

_>if( !isC ){
        
_>  B *b = new B;
  b->>f();
_>  // g()
_>  // e()
_>  // ...
_>  a = b;
        
_>}else{
        
_>   C *c = new C;        
   c->>f();
_>   // g()
_>   // e()
_>   // ...
_>   a = c;
    
_>}
_>


_>Вот это хотелось бы довести до рабочего состояния:

_>
    
_>auto x = isC ? new C: new B;
_>


Вопрос не понятен. Что мешает-то?
bool isC = true;

A *a = isC ? new C : new B;

  a->f();
  a->g()
  a->e()
  // ...
И каждый день — без права на ошибку...
Re[2]: сократить запись
От: sci_reseacher  
Дата: 20.05.16 14:10
Оценка:
Здравствуйте, B0FEE664, Вы писали:

ну попробуйте.

у a нет f(), g(), e(), ... .


BFE>Вопрос не понятен. Что мешает-то?

BFE>
BFE>bool isC = true;

BFE>A *a = isC ? new C : new B;

  a->>f();
  a->>g()
  a->>e()
BFE>  // ...
BFE>
Re: сократить запись
От: Erop Россия  
Дата: 20.05.16 18:53
Оценка:
Здравствуйте, sci_reseacher, Вы писали:

_>Как сократить запись и избавиться от копирования?


_>Вот это хотелось бы довести до рабочего состояния:

_>
    
_>auto x = isC ? new C: new B;
_>


решение в лоб (лучшее)

A *a ; 
D* d;   

if( !isC ){
  B *p = new B;
  a = p;
  d = p;
}else{
  C *p = new C;        
  a = p;
  d = p;
}
   d->f();
   // g()
   // e()
   // ...


Решение поизвратнее:
D* d = isC? new C : new D;
d->f(); // g, e,..
A* a = dynamic_cast<A*>(d);


Но у меня есть встречный вопрос: Что такое виртуальный деструкторКак это всё планируется разрушать?
Если у меня есть, например, d* или что-то вроде shared_ptr<a>, то да, а так не понятно...
Или это осталось за скобками?

На закуску, жаренная гузка:
struct A { int F; };
struct D { virtual void f() = 0; };
struct B : A, D { virtual void f() { F = 1; } };
struct C : D, A { virtual void f() { F = 2; } };

int main() {

    C v; // мона B v;
    D* d = &v;
    d->f();
    A* a = dynamic_cast<A*>(d);
    return a ? a->F : 0;
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: сократить запись
От: Кодт Россия  
Дата: 23.05.16 14:31
Оценка:
Здравствуйте, sci_reseacher, Вы писали:

_>Как сократить запись и избавиться от копирования?


1) вынести в интерфейс
class A {
public:
  virtual void afterborn() // TODO переопределить в B и C
  {
    afterborn_f();
    ....
    afterborn_z();
  }
protected:
  // если f()...z() по задумке не могут быть виртуальными, - сделать к ним внутренние интерфейсы
  virtual void afterborn_f() {} // TODO обязательно переопределить!
  .....
  virtual void afterborn_z() {}
};

.....
A* a = isC ? new C() : new B();
a->afterborn();


2) вынести в шаблон
template<class TA> TA* afterborn(TA* p) { p->f(); ... p->z(); return p; }

.....
A* a = isC ? afterborn(new C()) : afterborn(new B());


3) вынести в ад-хок шаблон "полиморфная лямбда"
auto afterborn = [](auto* p) { p->f(); ...; p->z(); return p; }
A* a = isC ? afterborn(new C()) : afterborn(new B());


4) вернуться к интерфейсу, сделать CRTP
template<class Self> class ABase {
public:
  Self* afterborn() {
    static Self* self = static_cast<Self*>(this);
    self->f(); ...; self->z();
    return self;
  }
  static Self* newborn() { return new Self()->afterborn(); }
};

class B: public ABase<B>, A, D { ..... };
class C: public ABase<B>, A, D { ..... };

.....
A* a = isC ? C::newborn() : B::newborn();
Перекуём баги на фичи!
Re[2]: сократить запись
От: Erop Россия  
Дата: 23.05.16 17:47
Оценка:
Здравствуйте, Кодт, Вы писали:

К>1) вынести в интерфейс

К>
К>class A {
К>public:
К>  virtual void afterborn() // TODO переопределить в B и C
К>


К>2) вынести в шаблон

К>
К>template<class TA> TA* afterborn(TA* p) { p->f(); ... p->z(); return p; }
К>


К>3) вынести в ад-хок шаблон "полиморфная лямбда"

К>4) вернуться к интерфейсу, сделать CRTP
К>
К>  static Self* newborn() { return new Self()->afterborn(); }
К>


На самом деле, у ТС уже был выделен отдельный специальный интерфейс для инициализации. Это был D.
При этом A был неполиморфным! Уж не знаю, фича ли это, и зачем нужны были отдельные классы A и D, но если предположить, что это всё не просто так, то, возможно, бывают разные версии интерфейса для использования: A1, A2, A3...
И/или разные интерфейсы инициализации, и комбинация An и Dn определяется MDT...

Соответственно, можно или в D добавить A* GetA(), ну или GetA1(), GetA2 и т. д.
Или в A добавить возможность получения интерфейса инициализации, или, как я предлагал где-то выше, можно ничего не добавлять, а переходить от D* к А* по dynamic_cast...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.