LINUX.ORG.RU

Вызов виртуальной функции из абстрактного класса.

 


0

1

С++

При попытке собрать нечто вроде:

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

void A::func(void)
{
	virtfunc();
}

class B: public A {
public:
	virtual void virtfunc(void);
}

void B::virtfunc(void)
{
	//...
}
Компилятор выдает всего лишь варнинг, а линковщик не находит виртуальные функции. Так вообще можно делать если нужно?

★★★

Последнее исправление: beastie (всего исправлений: 2)

Убери = 0, тогда заработает.

invy ★★★★★
()

А как ты себе представляешь вызов чисто виртуальной функции из A::func? Если хочешь вызывать, то нужно ее описать

four_str_sam
()

Компилируется без предупреждений, проблем не вижу.

unsigned ★★★★
()
Ответ на: комментарий от four_str_sam

В чем проблема?

#include <iostream>

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

void A::func()
{
    std::cout << "Trace A" << std::endl;
    virtfunc();
}

class B: public A {
public:
    virtual void virtfunc();
};

void B::virtfunc()
{
    std::cout << "Trace B" << std::endl;
}

int main() {
   B b; 
   b.virtfunc();
   std::cout << "----" << std::endl;
   b.func();
 
   return 0;
}

$ ./a.out
Trace B
----
Trace A
Trace B

fluorite ★★★★★
()

значит не весь код показываешь, в такой конструкции проблем нет.

mashina ★★★★★
()
class A {
public:
	virtual void virtfunc(void) = 0;
	
	void func(void);
};

void A::virtfunc(void) {
    //
}

void A::func(void)
{
	virtfunc();
}

class B: public A {
public:
	virtual void virtfunc(void);
};

void B::virtfunc(void)
{
	//
} 
NegatiV
()
Ответ на: комментарий от fluorite

Присоединяюсь, код рабочий, только:

   B b; 
   b.virtfunc();
   std::cout << "----" << std::endl;
   b.func();

тут «правильнее»

   A* b = new B(); 
   b->virtfunc();
   std::cout << "----" << std::endl;
   b->func();
   delete b;

art_corp
()
Последнее исправление: art_corp (всего исправлений: 1)

Ха блин, у меня этот пример тоже работает. Просто из реального кода вытаскивать не стал, там текста много. Короче выясняю.

normann ★★★
() автор топика

Вот, вызов виртуальной функции в конструкторе не работатет:

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

A::A()
{
	virtfunc();
}

class B: public A {
public:
	virtual void virtfunc(void);
};

void B::virtfunc(void)
{
	puts("B::virtfunc()");
}

А эта вирт. функция должна быть вызвана при иницализации объекта, и задано это должно быть единожды в родительском класссе. Я не нахожу других вариантов кроме как вызвать ее в конструкторе. Как побороть?

normann ★★★
() автор топика
Ответ на: комментарий от normann

нельзя в конструкторе, да. В конструкторе ее еще нет, как и в деструкторе уже нет. Делай статический конструктор, инициализируй там, что нужно.

anonymous
()
Ответ на: комментарий от fluorite

Это он, видимо, про фабрику. Типа

class A {
	A();
public:
	virtual void virtfunc(void) = 0;
        template<class T>
        static A* factory () {
             T* t = new T();
             t->virtfunc ();
             return t;
        }
};
...
A* a = A::factory<B> ();

Что, конечно, ужас, но никто же не ищет лёгких путей.

anonymous
()
Ответ на: комментарий от normann

А эта вирт. функция должна быть вызвана при иницализации объекта, и задано это должно быть единожды в родительском класссе. Я не нахожу других вариантов кроме как вызвать ее в конструкторе.

Функция, которая должна быть вызвана единожды при инициализации объекта — это и есть конструктор. Не нужна тут виртуальная функция вообще.

const86 ★★★★★
()
Ответ на: комментарий от normann

Естественно, что в конструкторе можно вызывать только те методы, инварианты объектов которых уже готовы. Конструктор производного класса еще не отработал, поэтому вызывать методы производного класса некорректно.

anonymous
()

Ясно, жаль конечно. А как было бы удобно. Всем спасибо.

normann ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.