Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Можно ли осуществить подобное без указателей.


Автор: Neitron 2.12.2005, 12:16
Собсно вот код

Код

class A{
public:
      virtual void f()=0;
};

class B: public A{
public:
       void f(){}
};

class C{
    A a;
public:
    C(): a( B() ){}
};


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

Автор: srd 2.12.2005, 12:27
Не понятно, чего хочешь добиться. Класс А является абстрактным, потому класс С не может содержать экземпляров класса А.

Автор: Neitron 2.12.2005, 12:31
Если сделать так.
Код

class A{
public:
      void f(){}
};
class B: public A{
public:
       void f(){ShowMessage("ssssssssssssss");}
};
class C{
    A a;
public:
    C(): a( B() ){a.f();}
};

То конструктор С() Покажет сообщение.
Но A::f() существует, и занимает память...

Мне нужен экземпляр класса B
Но чтобы знал он о методах только класса A.
Цитата

Не понятно, чего хочешь добиться. Класс А является абстрактным, потому класс С не может содержать экземпляров класса А.

По-моему конструктор класса C вполне ясно говорит чего я хочу.

Автор: chipset 2.12.2005, 12:36
Там занимать нечему, функции ж не копируються в каждый экземпляр класса.
Цитата(Neitron @ 2.12.2005, 02:31)
Но A::f() существует, и занимает память...

Малость не врубаюсь я, а как ты хочешь проделать эту операцию
Код
 C(): a( B() ){a.f();} 

без A::f? O_O

Автор: Neitron 2.12.2005, 12:39
chipset
Объясняю f() виртуальная и определянеся ри создании класса, через класс B...
Вообщем я понел, что без указателей это сделать невозможно.А жаль.

Автор: _hunter 2.12.2005, 12:40
конструктор-то говорит, но о чем он говорит ты, похоже, не знаеш...
+ класс B и так знает только о методах класса А ( ну и о своих ) -- о методах класса С он не знает ( если ты это имел в виду )

Автор: Neitron 2.12.2005, 12:41
Цитата(chipset @ 2.12.2005, 12:36)
  Там занимать нечему, функции ж не копируються в каждый экземпляр класса.

Не совсем

Код


class A{
public:
      void f(){}
};
class B: public A{
public:
       void f(){ShowMessage("ssssssssssssss");}
};

После этого существует две ф-ции A::f() и B::f()
При использовании виртуальных ф-ций cуществует только B::f() он обратится можно к ней и из класса A

Автор: _hunter 2.12.2005, 12:42
Цитата
f() виртуальная и определянеся ри создании класса, через класс B...

это и так понятно... а чем тебя это не устраивает/что ты хочеш изменить?

Автор: Neitron 2.12.2005, 12:44
Я хочу чтобы это работало... Это не компилируется.!
Видимо придется делать так...
Код

class A{
public:
      virtual void f()=0;
};
class B: public A{
public:
       void f(){}
       virtual ~f(){};
};
class C{
    A * a;
public:
    C(): a(new B() ){}
    ~C(){delete a;}
};

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

Автор: _hunter 2.12.2005, 12:46
если не объявиш а абстрактным -- тоже две функции будут _существовать_...
что тебе нужно так и не понял...
Добавлено @ 12:50
что такое virtual ~f(){}; ?
+ напиши не "хочу чтобы скомпилировалось" а задачу...
++ в чем проблема с "заботой об удалении"?

Автор: Neitron 2.12.2005, 12:50
Я знаю все о чем говорит конструктор.

Я хочу чтобы "a" знал только о методах A, но был создал при помощи B Без указателей...

Забей на
virtual ~f(){};

Я показал тот код который мне нужен.
В Виде указателей, хочу чтобы это было без указателей.

Автор: srd 2.12.2005, 12:50
Цитата(Neitron @ 2.12.2005, 19:44)
В этом случае придется заботится об удалении объекта... А я это делать не хотел...

Можно и не заботиться...
Код

#include <memory>

class A{
public:
      virtual void f()=0;
};

class B: public A{
public:
       void f(){}
};

class C{
    std::auto_ptr<A> a;    
public:
    C(): a(new B())
        {}
};

Или использовать ссылки

Автор: Neitron 2.12.2005, 12:54
Цитата(srd @ 2.12.2005, 12:50)
Или использовать ссылки

smile smile smile
Только я это уже сам понел=))))
Пока я тут спорил, мне пришла в голову мысль о ссылка и уже минут 10 у меня компилируется проект и я ждал выдаст он ошибку или нет...
Код

class A{
public:
      virtual void f()=0;
};
class B: public A{
public:
       void f(){ShowMessage("ssssssssssssss");}
};
class C{
    A &a;
public:
    C(): a( B() ){a.f();}
};

Всем спасибо. Как всегда никто не помог вовремя...

Автор: srd 2.12.2005, 12:55
Это у тебя фигня получилась. Неконстантные ссылки на временный объекты создавать нельзя.

Автор: Neitron 2.12.2005, 12:57
Почему временный?
Объект существует пока существует класс или я не прав?
Не проблема сделать её константной...

Автор: srd 2.12.2005, 14:29
Здесь B() создаёт временный объект, которым ты пытаешься проинициализировать неконстантую ссылку, что запрещено.
Код

C() : a(  B()  ) {a.f();}


По идее, надо так:
Код

#include <iostream>

class A{
public:
      virtual void f()const=0;
};

class B: public A{
public:
       void f()const{ std::cout << "test\n";}
};

class C{
    const A& a;
public:
    C(): a(B())
    {
            a.f();
    }
};

int main()
{
    C c;
}

gcc это компилирует, и получаемая программа работает правильно.
А вот VC7.1 скомпилировать такой код не может:
Код

error C2354: 'C::a' : initialization of reference member requires a temporary variable
error C2439: 'C::a' : member could not be initialized




Автор: Neitron 2.12.2005, 14:36
Когда я делаю так..
Код

class C{
    const A& a;
public:
    C(): a(B())
    {
            a.f();
    }
};

Билдер ругается на то что я вызываю не константные ф-ции...
Может тогда так?
Код

class C{
    A&const a;
public:
    C(): a(B())
    {
            a.f();
    }
};

Ф-ции не могут у меня быть константными.
Что-то ты хитришь, я не понимаю что ужасного в моем коде?
Никаких предупреждений у меня билдер вообще не пишит.
Очень хочу разобраться в этом моменте...

Автор: Neitron 2.12.2005, 14:56
Может это недостаток компилера от мелкомягких?

Автор: Neitron 2.12.2005, 15:10
Пришел к выводу, что лучше буду использовать указатели.

Автор: Vyacheslav 2.12.2005, 17:27
Цитата(srd @ 2.12.2005, 14:29)
Здесь B() создаёт временный объект, которым ты пытаешься проинициализировать неконстантую ссылку, что запрещено.

А чeм тут поможет константная ссылка? В любом случае это ошибка - инициализировать ссылку временным объектом, который к тому моменту, когда им пытаются воспользоваться посредством ссылки уже уничтожен. И сработала или не сработала программа - это не аргумент, по скольку при уничтожении объекта память не обязана быть очищена, то в приниципе код может и сработать на уничтоженном объекте

Автор: srd 2.12.2005, 17:42
Цитата(Vyacheslav @ 3.12.2005, 00:27)
А чeм тут поможет константная ссылка? В любом случае это ошибка - инициализировать ссылку временным объектом, который к тому моменту, когда им пытаются воспользоваться посредством ссылки уже уничтожен. И сработала или не сработала программа - это не аргумент, по скольку при уничтожении объекта память не обязана быть очищена, то в приниципе код может и сработать на уничтоженном объекте

Константная ссылка продлевает время жизни временного объекта. Пока ссылка не выйдет из области видимости, временный объект живёт.

Автор: blackofe 2.12.2005, 21:01
Neitron
не пойму, чем ты компилируешь. у меня vc++ выдал сразу две ошибки на строку:

Код

C(): a(B())    {    a.f(); }


error C2354: 'C::a' : initialization of reference member requires a temporary variable

error C2439: 'C::a' : member could not be initialized

что совершенно справедливо: выполнение нестатического метода требует наличие временного (хотя бы) объекта, а ты не можешь его создать, потому что A - класс абстрактный.
Добавлено @ 21:02
упс. пропустил продолжение темы smile.
Добавлено @ 21:04
Цитата(Neitron @ 2.12.2005, 12:50)
Я хочу чтобы "a" знал только о методах A, но был создал при помощи B Без указателей...

рассудим логически. ты хочешь, чтобы a знал только о методах A, но ведь среди методов A есть чисто виртуальные! как ты объяснишь компилятору, что они должны делать?

Автор: Earnest 4.12.2005, 21:33
Цитата(srd @ 2.12.2005, 17:42)
Константная ссылка продлевает время жизни временного объекта. Пока ссылка не выйдет из области видимости, временный объект живёт.


Неконстантный временный объект живет ровно столько же, просто некоторые компиляторы запрещают создание неконстантных временных объектов, справедливо считая это небезопасным.

Во время работы конструктора a показывает на существующий (временный !)объект, и код отработает. Но потом-то а останется в классе! И будет показывать на мусор.
Если нужно, чтобы код отработал только в конструкторе, заведи в нем локальную переменную И и сделай вызов.

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

Автор: Neitron 5.12.2005, 11:17
Код

как ты объяснишь компилятору, что они должны делать? 

Я хотел делать это также как мог делать в этом коде...

Код

const A a = B();

Но я уже уловил суть.... То что я хотел, этого видимо не сделать....
Earnest
Я давно сам в этом разобрался.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)