Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.81/21: Рейтинг темы: голосов - 21, средняя оценка - 4.81
0 / 0 / 0
Регистрация: 05.04.2015
Сообщений: 32

Переопределение виртуальной функции в разных файлах наследственных классов

10.07.2019, 18:18. Показов 4741. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет ! У меня есть проблема, допустим есть класс Base.h и соответственно он имеет Base.cpp в котором записана реализация функциии допустим virtual int foo() возвращает любое число не имеет смысла.
В классе допустим Second.cpp(у него тоже есть заголовочный файл Second.h где обявлена функция int foo() без virtual) переопределим эту функцию чтобы она возвращала некое иное значение, в итоге при комплияции оказывается то что мы обращаемся в любом случае к функции класса родителя. Помогите пожалуйста, извиняюсь за ошибки и корявую терминологию.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.07.2019, 18:18
Ответы с готовыми решениями:

Переопределение виртуальной функции
Всем доброй ночи :) Есть базовый абстрактный класс и два производных класса (А и В), в которых я пытяюсь переопределить виртуальную...

Наследование. Переопределение виртуальной функции
Здравствуйте. Нужно создать классы, наследование. Переопределить для каждого класса виртуальную функцию Print. К каждому классу добавить...

Переопределение виртуальной функции в производном классе
Здравствуйте, я столкнулся с проблемой при переопределения виртуальной функции в производном классе. Код: class dist { // base ...

16
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
10.07.2019, 18:26
Цитата Сообщение от Varag Посмотреть сообщение
в итоге при комплияции оказывается то что мы обращаемся в любом случае к функции класса родителя.
Нет, это не так. От расположения кода по файлам это не зависит. У тебя просто неправильно написан код. Вот простейший пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Base
{
public:
  virtual int foo() { return 0; }
};
 
class Second: public Base
{
public:
  int foo() { return 1; }
};
 
int main()
{
  Base* b1 = new Base();
  Base* b2 = new Second();
  std::cout << b1->foo() << std::endl << b2->foo() << std::endl;
}
Вывод:
Code
1
2
0
1
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
10.07.2019, 18:38
Цитата Сообщение от Varag Посмотреть сообщение
В классе допустим Second.cpp
Это не класс, а файл.
Цитата Сообщение от Varag Посмотреть сообщение
где обявлена функция int foo() без virtual
А почему она должна быть virtual?
Ваш класс/файл
Цитата Сообщение от Varag Посмотреть сообщение
Second.h
хотя бы наследник вашего
Цитата Сообщение от Varag Посмотреть сообщение
Base.h
?
Цитата Сообщение от Varag Посмотреть сообщение
переопределим эту функцию чтобы она возвращала некое иное значение, в итоге при комплияции оказывается то что мы обращаемся в любом случае к функции класса родителя
И как вы это определили?
Цитата Сообщение от Varag Посмотреть сообщение
Помогите пожалуйста
Можете объявить так:
C++
1
int foo() override
в наследнике.

А вообще без кода, понять в чем именно ваша проблема - сложно, так что в студию.

Добавлено через 7 минут
Цитата Сообщение от Varag Посмотреть сообщение
мы обращаемся в любом случае к функции класса родителя
Цитата Сообщение от Varag Посмотреть сообщение
virtual int foo()
Она в базовом точно виртуальная? Ибо очень похоже, что нет)
C++
1
2
3
4
5
6
7
8
9
10
11
12
struct base { 
    int foo() const { return 123; } 
};
struct derived : base { 
    int foo() const { return 2019; } 
};
 
int main()
{
    base const& b = derived();
    std::cout << b.foo(); // prints 123
}
если с виртуал то,
C++
1
2
3
4
5
6
7
8
9
10
11
12
struct base { 
    virtual int foo() const { return 123; } 
};
struct derived : base { 
    int foo() const { return 2019; } 
};
 
int main()
{
    base const& b = derived();
    std::cout << b.foo(); // prints 2019
}
В наследнике virtual не играет значения.
1
0 / 0 / 0
Регистрация: 05.04.2015
Сообщений: 32
10.07.2019, 18:40  [ТС]
Base.h:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma once
 
#include <SFML/Graphics.hpp>
#include <iostream>
 
class block
{
public:
    block(bool is_solid = false);
    bool getSolid();
    virtual sf::Vector2i getTexCoord();
private:
    bool is_solid;
};
Base.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "block.h"
 
block::block(bool is_solid)
{
    this->is_solid = is_solid;
}
 
bool block::getSolid()
{
    return is_solid;
}
 
sf::Vector2i block::getTexCoord()
{
    std::cout << "Void" << std::endl;
    return sf::Vector2i(0,0);
}
blockFloor.h:
C++
1
2
3
4
5
6
7
8
9
10
11
#pragma once
#include "block.h"
#include <iostream>
 
class blockFloor : public virtual block
{
public:
    blockFloor(bool is_solid) : block(is_solid) {}
    virtual sf::Vector2i getTexCoord() override;
private:
};
blockFloor.cpp:
C++
1
2
3
4
5
6
7
#include "blockFloor.h"
 
sf::Vector2i blockFloor::getTexCoord()
{
    std::cout<<"Floor"<<std::endl;
    return sf::Vector2i(1,0);
}

Вот пример классов перепробовал всё результата нет(
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
10.07.2019, 18:42
А кода использования нет. А там чаще всего ошибка.
Цитата Сообщение от Varag Посмотреть сообщение
public virtual block
зачем virtual?
Цитата Сообщение от Varag Посмотреть сообщение
virtual sf::Vector2i getTexCoord() override;
А здесь зачем? Новое любимое слово?
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
10.07.2019, 18:44
Цитата Сообщение от Varag Посмотреть сообщение
Вот пример классов перепробовал всё результата нет(
Код где бы вызываете метод, тоже давайте.
1
0 / 0 / 0
Регистрация: 05.04.2015
Сообщений: 32
10.07.2019, 18:45  [ТС]
Виноват вот он:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include "blockMap.h"
 
blockMap::blockMap()
{
    size = sf::Vector2i(32, 32);
}
 
blockMap::blockMap(sf::Vector2i size)
{
    this->size = size;
 
    blocks.resize(size.x * size.y);
}
 
void blockMap::generate()
{
    shipAtlas.loadFromFile("textures\\shipTex.png");
    vertices.setPrimitiveType(sf::Quads);
    vertices.resize(4 * size.x * size.y);
    states.texture = &shipAtlas;
 
    float tileStep = 64;
    sf::Vector2i texCoord;
    for (int y = 0; y < size.y; y++)
    {
        for (int x = 0; x < size.x; x++)
        {
            int i = 1 + rand() % 3;
            if(i==1)
            blocks.push_back(new blockFloor(false));
            else
            blocks.push_back(new blockWall(true));
 
            texCoord = blocks[x + y * size.x].getTexCoord(); // Вот место где вызывается функция
 
            sf::Vertex* quad = &vertices[(x + y * size.x) * 4];
 
            quad[0].position = sf::Vector2f(x * blockSize, y * blockSize);
            quad[1].position = sf::Vector2f((x + 1) * blockSize, y * blockSize);
            quad[2].position = sf::Vector2f((x + 1) * blockSize, (y + 1) * blockSize);
            quad[3].position = sf::Vector2f(x * blockSize, (y + 1) * blockSize);
 
            quad[0].texCoords = sf::Vector2f((texCoord.x + 0) * tileStep, (texCoord.y + 0) * tileStep);
            quad[1].texCoords = sf::Vector2f((texCoord.x + 1) * tileStep, (texCoord.y + 0) * tileStep);
            quad[2].texCoords = sf::Vector2f((texCoord.x + 1) * tileStep, (texCoord.y + 1) * tileStep);
            quad[3].texCoords = sf::Vector2f((texCoord.x + 0) * tileStep, (texCoord.y + 1) * tileStep);
            //quad[0].color = sf::Color::Red;
            //quad[1].color = sf::Color::Blue;
            //quad[2].color = sf::Color::Yellow;
            //quad[3].color = sf::Color::Green;
        }
    }
}
 
void blockMap::draw(sf::RenderWindow& wind)
{
    wind.draw(vertices, states);
}
Вернул к виду с которым я изначально пытался работать blockFloor.h:
C++
1
2
3
4
5
6
7
8
9
10
11
#pragma once
#include "block.h"
#include <iostream>
 
class blockFloor : public block
{
public:
    blockFloor(bool is_solid) : block(is_solid) {}
    sf::Vector2i getTexCoord() override;
private:
};
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
10.07.2019, 18:53
Лучший ответ Сообщение было отмечено Varag как решение

Решение

Цитата Сообщение от Varag Посмотреть сообщение
blocks[x + y * size.x].getTexCoord()
Если ты через точку вызываешь, то, похоже, что blocks у тебя не из указателей. Либо, учитывая верхний new, ты его разыменовываешь. А значит, открываем книжку и читаем про полиморфизм еще раз.

Добавлено через 3 минуты
blocks должен быть вектором (или что там у тебя) из указателей на класс block. И вызов тогда будет
C++
1
blocks[x + y * size.x]->getTexCoord();
1
0 / 0 / 0
Регистрация: 05.04.2015
Сообщений: 32
10.07.2019, 18:55  [ТС]
Заработало, спасибо большое!
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
10.07.2019, 18:59
У тебя указатель на вектор. А надо вектор указателей.
C++
1
std::vector<block*> blocks;
В идеале, с умными указателями. Либо ручками потом память очищай.
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
10.07.2019, 19:00
Цитата Сообщение от Varag Посмотреть сообщение
Подобное использовать ?
C++
1
std::vector<block*> blocks;
1
0 / 0 / 0
Регистрация: 05.04.2015
Сообщений: 32
10.07.2019, 19:01  [ТС]
Да я так и сделал, немного переволновался.
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
10.07.2019, 19:02
Цитата Сообщение от Varag Посмотреть сообщение
class blockFloor : public virtual block
virtual - убрать, здесь роль virtual немного другая чем с функциями.
0
0 / 0 / 0
Регистрация: 05.04.2015
Сообщений: 32
11.07.2019, 15:19  [ТС]
Проснулся с утра открыл код задебажил и тут ошибка:
C++
1
texCoord = blocks[x + y * size.x]->getTexCoord();
На эту строку ошибка ->Вызвано исключение по адресу 0x00007FF7C5FC1118 в ImLearnThisShit.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0x0000000000000000.
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
11.07.2019, 15:22
Varag, значит, у тебя в blocks[x + y * size.x] лежит нулевой указатель. Ищи ошибку в коде, почему ты обращаешься туда, где объекта не создавал. Это уже ошибка в логике программы а не в той теме, о которой ты спрашивал в начале про виртуальные функции. Они тут не при чем.
1
0 / 0 / 0
Регистрация: 05.04.2015
Сообщений: 32
11.07.2019, 15:29  [ТС]
Я уже исправил но костылём, можно поинтересовать в этой теме или лучше новую создать ? Проблема оказалась в том что почему то когда я в вектор добавлял с помощью push_back новый экземпляр класса добавлялся нулевой объект.


C++
1
2
3
4
if(i==1)
            blocks[x + y * size.x] = new blockFloor(false);
            else
            blocks.push_back(new blockWall(true));
Вот пример верхнее условие спокойной выполняется, нижнее же видимо создаёт нулевой указатель
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
11.07.2019, 15:30
Цитата Сообщение от Varag Посмотреть сообщение
можно поинтересовать в этой теме или лучше новую создать ?
Новую. Не нужно сваливать все в одну кучу.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
11.07.2019, 15:30
Помогаю со студенческими работами здесь

Проблема классов в разных файлах
Вообщем, замучался я с этими файлами и заголовками. Код кидать не буду, ибо проблема не в нем. Условно: 1) У нас есть класс A,...

Взаимодействие классов в разных файлах
Я создаю два класса, которые находятся в отдельных файлах. В main.cpp объявляю объекты типа этих классов. Мне нужно, чтобы функция f1 из...

Переопределение публичной виртуальной функции как private
struct Foo { public: virtual void show() { std::cout &lt;&lt; &quot;Foo&quot; &lt;&lt; std::endl; } }; struct Bar: public...

Объявлние классов в разных заголовочных файлах
Приветствую всех участников форума. Есть 2 класса А и В. Каждый из содержит указатель на другой класс. Как сделать объявление классов в...

полу значения переменных из классов с одинаковыми именами, хранящимися в разных файлах
Добрый день всем. Возникла такая задача. Есть несколько файлов: config_1.php, config_2.php, config_3.php. В каждом из них есть класс с...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru