Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.76/21: Рейтинг темы: голосов - 21, средняя оценка - 4.76
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
1

Invalid use of incomplete type

27.05.2016, 17:24. Показов 3963. Ответов 3
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть вот такой код паттерна Observer:
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <iostream>
#include <algorithm>
#include <memory>
#include <vector>
 
class Observer;
 
class Subject
{
public:
    virtual void registerObserver(Observer* obs) = 0;
    virtual void removeObserver(Observer* obs) = 0;
    virtual void notifyObservers() = 0;
 
    virtual ~Subject() = default;
};
 
class WeatherData : public Subject
{
private:
    std::vector<std::shared_ptr<Observer>> observers;
    float temperature, humidity, pressure;
 
public:
    void registerObserver(Observer* obs) override
    {
        observers.push_back(std::make_shared<Observer>(obs));
    }
    void removeObserver(Observer* obs) override
    {
        auto it = std::find(observers.cbegin(), observers.cend(), obs);
        if (it != observers.cend())
            observers.erase(it);
    }
    void notifyObservers() override
    {
        for (std::shared_ptr<Observer> sp : observers) sp->update(temperature, humidity, pressure);
    }
 
    void measurementsChanged()
    {
        notifyObservers();
    }
 
    void setMeasurements(float temp, float hum, float press)
    {
        temperature = temp;
        humidity = hum;
        pressure = press;
 
        measurementsChanged();
    }
};
 
class DisplayElement
{
public:
    virtual void display() = 0;
    virtual ~DisplayElement() = default;
};
 
class Observer
{
public:
    virtual void update(float temp, float humidity, float pressure) = 0;
    virtual ~Observer() = default;
};
 
class CurrentConditionsDisplay : public Observer, public DisplayElement
{
private:
    float temperature, humidity, pressure;
    std::shared_ptr<Subject> spWeatherData;
 
public:
    CurrentConditionsDisplay(std::shared_ptr<Subject> subj) :
        spWeatherData(subj)
    {
        spWeatherData->registerObserver(this);
    }
 
    void update(float temp, float hum, float press) override
    {
        temperature = temp;
        humidity = hum;
        pressure = press;
        display();
    }
 
    void display() override
    {
        std::cout << "Temp: " << temperature << "\n";
        std::cout << "Humidity: " << humidity << "\n";
        std::cout << "Pressure: " << pressure << "\n";
    }
};
 
int main()
{
    std::shared_ptr<WeatherData> weatherData(new WeatherData());
    std::unique_ptr<CurrentConditionsDisplay> currentCD(new CurrentConditionsDisplay(weatherData));
 
    weatherData->setMeasurements(80, 65, 30);
    weatherData->setMeasurements(82, 70, 29);
    weatherData->setMeasurements(78, 90, 32);
}
На 37 строке возникает ошибка компиляции:
Кликните здесь для просмотра всего текста
invalid use of incomplete type 'class Observer'
for (std::shared_ptr<Observer> sp : observers) sp->update(temperature, humidity, pressure);
Не совсем понимаю в чем проблема.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.05.2016, 17:24
Ответы с готовыми решениями:

Error: Invalid use of incomplete type
Всем доброго вечера, возникла проблема в следующем коде. Я скорее всего не замечаю какой-то мелочи....

Incomplete type used in nested type specifier - Итерация по списку аргументов
Здравствуйте! Пытаюсь написать утилитарную структуру для применения шаблонной функции на списке...

Incomplete type и шаблоны
Очень глупый вопрос: почему первый пример не работает, а второй работает? Ну, то есть логику по...

Ошибка: incomplete type is not allowed
Когда я хочу скопировать значение из структуры в массив, то выскакивает такая ошибка.... Что...

3
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
27.05.2016, 17:28 2
notAll, попробуйте совместить гугл перевод ошибки и 6 строку
1
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
30.05.2016, 23:37  [ТС] 3
Признаю, ступил. Но с кодом все еще есть проблемы - теперь вылетает при выполнении. На голых указателях работает, с "умными" не хочет. В чем может быть проблема?
Кликните здесь для просмотра всего текста
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <iostream>
#include <algorithm>
#include <memory>
#include <vector>
 
class Observer
{
public:
    virtual void update(float temp, float humidity, float pressure) = 0;
    virtual ~Observer() = default;
};
 
class Subject
{
public:
    virtual void registerObserver(Observer* obs) = 0;
    virtual void removeObserver(Observer* obs) = 0;
    virtual void notifyObservers() = 0;
 
    virtual ~Subject() = default;
};
 
class WeatherData : public Subject
{
private:
    std::vector<std::shared_ptr<Observer>> observers;
    float temperature, humidity, pressure;
 
public:
    void registerObserver(Observer* obs) override
    {
        observers.push_back(std::shared_ptr<Observer>(obs));
    }
    void removeObserver(Observer* obs) override
    {
        auto it = std::find(observers.begin(), observers.end(), std::shared_ptr<Observer>(obs));
        if (it != observers.end())
            observers.erase(it);
    }
    void notifyObservers() override
    {
        for (std::shared_ptr<Observer> sp : observers) sp->update(temperature, humidity, pressure);
    }
 
    void measurementsChanged()
    {
        notifyObservers();
    }
 
    void setMeasurements(float temp, float hum, float press)
    {
        temperature = temp;
        humidity = hum;
        pressure = press;
 
        measurementsChanged();
    }
};
 
class DisplayElement
{
public:
    virtual void display() = 0;
    virtual ~DisplayElement() = default;
};
 
class CurrentConditionsDisplay : public Observer, public DisplayElement
{
private:
    float temperature, humidity, pressure;
    std::shared_ptr<Subject> spWeatherData;
 
public:
    CurrentConditionsDisplay(std::shared_ptr<Subject> subj) :
        spWeatherData(subj)
    {
        spWeatherData->registerObserver(this);
    }
 
    void update(float temp, float hum, float press) override
    {
        temperature = temp;
        humidity = hum;
        pressure = press;
        display();
    }
 
    void display() override
    {
        std::cout << "Temp: " << temperature << "\n";
        std::cout << "Humidity: " << humidity << "\n";
        std::cout << "Pressure: " << pressure << "\n";
    }
};
 
int main()
{
    std::shared_ptr<WeatherData> weatherData(new WeatherData());
    std::unique_ptr<CurrentConditionsDisplay> currentCD(new CurrentConditionsDisplay(weatherData));
 
    weatherData->setMeasurements(80, 65, 30);
    weatherData->setMeasurements(82, 70, 29);
    weatherData->setMeasurements(78, 90, 32);
}


Добавлено через 12 часов 52 минуты
Значит, для развязывания проблемы циклических ссылок я решил использовать weak_ptr. Но программа постоянно вылетает с ексепшином bad_weak_ptr (да так вылетает что даже пересборка с очисткой не помогает вывести ее из ступора - приходиться перегружать ПК). Проблема кроется где то в вызове shared_from_this() (44 строка), но как ее решить? Подкиньте хоть какую то идею. Вот переделанный код:
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <iostream>
#include <algorithm>
#include <memory>
#include <vector>
 
class DisplayElement
{
public:
    virtual void display() = 0;
 
    virtual ~DisplayElement() = default;
};
 
class Observer
{
public:
    virtual void update(float temp, float humidity, float pressure) = 0;
 
    virtual ~Observer() = default;
};
 
class Subject
{
public:
    virtual void registerObserver(std::shared_ptr<Observer>) = 0;
 
    virtual void removeObserver(std::shared_ptr<Observer>) = 0;
 
    virtual void notifyObservers() = 0;
 
    virtual ~Subject() = default;
};
 
class CurrentConditionsDisplay :
        public Observer, public DisplayElement, public std::enable_shared_from_this<CurrentConditionsDisplay>
{
private:
    float temperature, humidity, pressure;
    std::weak_ptr<Subject> spWeatherData;
 
public:
    CurrentConditionsDisplay(std::shared_ptr<Subject> subj) : spWeatherData(subj)
    {
        spWeatherData.lock()->registerObserver(shared_from_this());
    }
 
    void update(float temp, float hum, float press) override
    {
        temperature = temp;
        humidity = hum;
        pressure = press;
        display();
    }
 
    void display() override
    {
        std::cout << "Temp: " << temperature << "\n";
        std::cout << "Humidity: " << humidity << "\n";
        std::cout << "Pressure: " << pressure << "\n";
    }
};
 
class WeatherData : public Subject
{
private:
    std::vector<std::shared_ptr<Observer>> observers;
    float temperature, humidity, pressure;
 
public:
    void registerObserver(std::shared_ptr<Observer> obs) override
    {
        observers.push_back(obs);
    }
 
    void removeObserver(std::shared_ptr<Observer> obs) override
    {
        auto it = std::find(observers.cbegin(), observers.cend(), obs);
        if (it != observers.cend())
            observers.erase(it);
    }
 
    void notifyObservers() override
    {
        for (auto sp : observers) sp->update(temperature, humidity, pressure); //TODO
    }
 
    void measurementsChanged()
    {
        notifyObservers();
    }
 
    void setMeasurements(float temp, float hum, float press)
    {
        temperature = temp;
        humidity = hum;
        pressure = press;
 
        measurementsChanged();
    }
};
 
int main()
{
    std::shared_ptr<WeatherData> weatherData(new WeatherData());
    std::shared_ptr<CurrentConditionsDisplay> currentCD(new CurrentConditionsDisplay(weatherData));
 
    weatherData->setMeasurements(80, 65, 30);
}
Добавлено через 3 минуты

Не по теме:

Модераторы, переименуйте тему на что то вроде "Проблемы с использованием умных указателей"

0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
31.05.2016, 09:03 4
Лучший ответ Сообщение было отмечено notAll как решение

Решение

Цитата Сообщение от notAll Посмотреть сообщение
Подкиньте хоть какую то идею
shared_from_this из конструктора не надо вызывать.
shared_from_this из конструктора еще не видит никаких shared_ptr, к которым мог бы быть привязан наш указатель. Ты тут нарушаешь, так сказать, причинно-следственную связь. Отсюда это исключение.
Побороть (без значительной переделки твоего кода) можно так:
Кликните здесь для просмотра всего текста
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <iostream>
#include <algorithm>
#include <memory>
#include <vector>
 
class Observer;
 
class Subject
{
public:
    virtual void registerObserver(std::shared_ptr<Observer> obs) = 0;
    virtual void removeObserver(std::shared_ptr<Observer> obs) = 0;
    virtual void notifyObservers() = 0;
 
    virtual ~Subject() = default;
};
 
class Observer
{
public:
    virtual void update(float temp, float humidity, float pressure) = 0;
    virtual ~Observer() = default;
};
 
class WeatherData : public Subject
{
private:
    std::vector<std::shared_ptr<Observer>> observers;
    float temperature, humidity, pressure;
 
public:
    void registerObserver(std::shared_ptr<Observer> obs) override
    {
        observers.push_back(obs);
    }
    void removeObserver(std::shared_ptr<Observer> obs) override
    {
        auto it = std::find(observers.begin(), observers.end(), obs);
        if (it != observers.cend())
            observers.erase(it);
    }
    void notifyObservers() override
    {
        for (std::shared_ptr<Observer> & sp : observers)
            sp->update(temperature, humidity, pressure);
    }
 
    void measurementsChanged()
    {
        notifyObservers();
    }
 
    void setMeasurements(float temp, float hum, float press)
    {
        temperature = temp;
        humidity = hum;
        pressure = press;
 
        measurementsChanged();
    }
};
 
class DisplayElement
{
public:
    virtual void display() = 0;
    virtual ~DisplayElement() = default;
};
 
class CurrentConditionsDisplay
    : public Observer
    , public DisplayElement
    , public std::enable_shared_from_this<CurrentConditionsDisplay>
{
private:
    float temperature, humidity, pressure;
    std::weak_ptr<Subject> spWeatherData;
 
    CurrentConditionsDisplay(std::weak_ptr<Subject> subj)
        : spWeatherData(subj)
    {
        std::shared_ptr<CurrentConditionsDisplay> ptr(this);
 
        spWeatherData.lock()->registerObserver(ptr);
    }
 
public:
    static std::shared_ptr<CurrentConditionsDisplay> create(std::weak_ptr<Subject> subj)
    {
        return (new CurrentConditionsDisplay(subj))->shared_from_this();
    }
 
    void update(float temp, float hum, float press) override
    {
        temperature = temp;
        humidity = hum;
        pressure = press;
        display();
    }
 
    void display() override
    {
        std::cout << "Temp: " << temperature << "\n";
        std::cout << "Humidity: " << humidity << "\n";
        std::cout << "Pressure: " << pressure << "\n";
    }
};
 
int main()
{
    std::shared_ptr<WeatherData> weatherData(new WeatherData());
 
    std::shared_ptr<CurrentConditionsDisplay> currentCD(
        CurrentConditionsDisplay::create(weatherData)
    );
 
    weatherData->setMeasurements(80, 65, 30);
    weatherData->setMeasurements(82, 70, 29);
    weatherData->setMeasurements(78, 90, 32);
}
1
31.05.2016, 09:03
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.05.2016, 09:03
Помогаю со студенческими работами здесь

Field `.` has incomplete type boost::weak_ptr
Здравствуйте! Интересует вопрос: если член класса имеет тип weak_ptr, то требуется определение...

Incomplete type при определении преобразования (каста)
Есть кейс, при котором нужно определить преобразование первого класса во второй и второго в первый....

Шаблонный класс. Ошибка : aggregate 'Box<info*> ob' has incomplete type and cannot be defined
Здравствуйте! Снова возникла небольшая проблема. Создал шаблонный класс: box.h #ifndef...

Найти причины и способы исправления ошибки: Error - member access into incomplete type 'Node'
Здравствуйте. Пытаюсь обратиться к переменной структуры, добавить в неё (в вектор) новый элемент,...

Ошибка "aggregate 'main()::mmm x' has incomplete type"
выдаёт ошибку In function 'int main()': 11:13: error: aggregate 'main()::mmm x' has incomplete...

Реализовать класс Node ([Error] field 'next' has incomplete type 'Node')
#include &lt;iostream&gt; using namespace std; class Node { private: int value; Node next; ...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru