Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> list 
:(
    Опции темы
nikitao
Дата 14.11.2005, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кот-программист
***


Профиль
Группа: Завсегдатай
Сообщений: 1206
Регистрация: 30.8.2005
Где: Спб

Репутация: 1
Всего: 26



Void,да, ты меня обыграл smile ,но этот пример несерьезен(класс компелируется как "единое целое").

Цитата
Потому что Pics в точке инстанциирования std::list является неполным типом.

Вот это уже интереснее,но тогда вопрос:Зачем использывать такой синтаксис.В таком случае мы не выигрываем ни в чем,а можем ли мы выиграть при таком вообще???(Мне приходит в голову только когда надо структуру или класс с одинаковым именем и разным содержанием в разных классах создать)


Цитата(wpp @ 14.11.2005, 21:43)
Спасибо, Страуструп есть у меня. Объясняет он ужасно (IMHO). В кучу ничего из прочитанного собрать не удалось
Его сходу не поймешь.Для того чтобы его понять надо уже знать С++. smile



--------------------
Жизнь - печальная штука.
PM MAIL ICQ Skype GTalk   Вверх
Void
Дата 14.11.2005, 21:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



Цитата(nikitao @ 14.11.2005, 23:11)
Вот это уже интереснее,но тогда вопрос:Зачем использывать такой синтаксис.В таком случае мы не выигрываем ни в чем,а можем ли мы выиграть при таком вообще???(Мне приходит в голову только когда надо структуру или класс с одинаковым именем и разным содержанием в разных классах создать)

Да ничего мы не выигрываем smile Человек спросил, почему не компилируется, я показал, как можно исправить. В большинстве случаев, я бы предпочел вложенным классам пространства имен.

Впрочем, вот вполне разумный пример использования вложенных классов для скрытия реализации:
Код
template <class T>
class Matrix {
    T *p;
    size_t rows_, cols_;
    template <class T>
    class Row {
        T *p_;
        size_t cols_;
    public:
        Row(T *p, size_t cols) : p_(p), cols_(cols) { }
        T &operator [](size_t i) {
            assert(i < cols_);
            return p_[i];
        }
        const T &operator [](size_t i) const {
            assert(i < cols_);
            return p_[i];
        }
    };
public:
    Matrix(size_t rows, size_t cols) : rows_(rows), cols_(cols),
        p(new T[rows * cols]) { }
    ~Matrix() {
        delete[] p;
    }
    Row<T> operator [](size_t i) {
        assert(i < rows_);
        return Row<T>(p + i * cols_, cols_);
    }
    const Row<T> operator [](size_t i) const {
        assert(i < rows_);
        return Row<T>(p + i * cols_, cols_);
    }
};



--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Chaos A.D.
Дата 15.11.2005, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 172
Регистрация: 16.1.2005
Где: 09 RUS

Репутация: 6
Всего: 7



Цитата(Void @ 14.11.2005, 19:36)
std::list<class Pics *> pics;

Вот уж не знал, что так можно делать. Есть три вопроса.
1) Наверное, это эквивалентно предварительному объявлению класса?
2) Это в стандарте?
3) Где же такая фича описывается? Не встречал даже у страуструпа.
--------------------
Надо смеяться над тем, что тебя мучит, иначе не сохранишь равновесия, иначе мир сведет тебя с ума...Ken Kesey - One Flew Over The Cocoo's Nest
PM MAIL   Вверх
Void
Дата 15.11.2005, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



Цитата(Chaos @ 15.11.2005, 12:37)
1) Наверное, это эквивалентно предварительному объявлению класса?

Похоже, что да. Компилируется и работает даже вот это:
Код
#include <list>

int main() {
    std::list<class A*> lst;
    return lst.size();
}

Дело, судя по всему, в том, что указатель на неполный тип является полным типом.
Цитата(Chaos @ 15.11.2005, 12:37)
2) Это в стандарте?

Да. Точный пункт не укажу, упоминания равномерно размазаны по тексту.
Цитата(Chaos @ 15.11.2005, 12:37)
3) Где же такая фича описывается? Не встречал даже у Страуструпа.

Я тоже. За подробными объяснениями, наверное, лучше обратиться к гуру smile


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Neitron
Дата 15.11.2005, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 580
Регистрация: 3.10.2005
Где: Москва

Репутация: 2
Всего: 5



На самом деле, это все обыкновенное следствие.
О котором можно догадаться видимо.
Класс и структура, являются производными от пространства имен
А значит в них же можно объвлять новые типы, как и в простом пространстве.
class Name;
Всегда являлся обявлением класса, а если есть объявление то можно использовать указатель на этот тип, но не сам тип.
Никто никогда не отменял этого

Код

class A;
list<A *> B;

Видно что это ничем не отличается от
Код

list<class A *> B;

Более короткая запись.

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

Это сообщение отредактировал(а) Neitron - 15.11.2005, 14:48


--------------------
Хороший программист никогда ничего не делает хорошо с первого раза. Он понимает важность патчей.
Ⓘ ⓁⒾⓀⒺ ⓂⓄⓏⒾⓁⓁⒶ
PM MAIL   Вверх
Neitron
Дата 15.11.2005, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 580
Регистрация: 3.10.2005
Где: Москва

Репутация: 2
Всего: 5



Хочу добавить, что упоминание о вложенных структурах есть например в 10.8


--------------------
Хороший программист никогда ничего не делает хорошо с первого раза. Он понимает важность патчей.
Ⓘ ⓁⒾⓀⒺ ⓂⓄⓏⒾⓁⓁⒶ
PM MAIL   Вверх
Earnest
Дата 15.11.2005, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(Neitron @ 15.11.2005, 11:49)

Код

class A;
list<A *> B;

Видно что это ничем не отличается от
Код

list<class A *> B;


Не совсем. В глобальном скопе - да, а если это дело поместить внутрь класса, то в первом случае объявляется вложенный класс, а во втором случае компилятор считает, что class А - внешний. По крайней мере, MSVC так себя ведет. Так что, Void, твой пример из начала темы, работать не будет (компилироваться будет, но будут ошибки линкера - в MSVC!) - потому то классы A - разные.

Что касается примера со списком указателей на неполный класс - то принцип простой: инстационируется только то, то реально используется. Поэтому все будет компилироваться и работать до тех, пока не потребуется обратиться внутрь класса A.




--------------------
...
PM   Вверх
Void
Дата 16.11.2005, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



Цитата(Earnest @ 16.11.2005, 00:29)
(компилироваться будет, но будут ошибки линкера - в MSVC!)

Не будут. Будут ошибки компиляции. Посыпаю пеплом голову smile
Код
#include <list>

class A {
    std::list<struct B*> lst;
public:
    struct B {
        int x;
        void foo() { }
    };
    A() { }
    void foo() {
        lst.push_back(new B);
        lst.front()->foo();
    }
};

int main() {
    A c;
    c.foo();
}

Цитата
test.cpp(12) : error C2664: 'std::list<_Ty>::push_back' : cannot convert paramet
er 1 from 'A::B *' to 'B *const &'
        with
        [
            _Ty=B *
        ]
        Reason: cannot convert from 'A::B *' to 'B *const '
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-
style cast or function-style cast
test.cpp(13) : error C2027: use of undefined type 'B'
        test.cpp(4) : see declaration of 'B'
test.cpp(13) : error C2227: left of '->foo' must point to class/struct/union/gen
eric type




--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Earnest
Дата 16.11.2005, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Ну да, конечно, это я поторопилась и забыла, что был еще код, использующий это класс(подумала, что уже пробовали скомпилировать и получилось). Но точно знаю, что такой фокус не прокатывает внутри класса. А жаль.
Тоже самое для friend: если написать friend class BBB, то в локальном скопе класса не прокатит за предварительное объявление вложенного класса. А хотелось бы.
Интересно, это стандарт или частное поведение MSVC?


--------------------
...
PM   Вверх
Void
Дата 16.11.2005, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



Цитата(Earnest @ 16.11.2005, 22:41)
Интересно, это стандарт или частное поведение MSVC?

Похоже, стандарт. Comeau ругается аналогичным образом. Вот только до конкретных указаний я все никак дойти не могу.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
LPBOY
Дата 7.12.2005, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

Репутация: 20
Всего: 20



Void, интересную штуку ты откопал. smile

Код

#include <list>

struct A
{
    std::list<struct B*> l; // компилится без проблем
};

int main()
{
A a;
}


А что это? В стандарте не нашел?
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
Daevaorn
Дата 7.12.2005, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(LPBOY @ 7.12.2005, 13:36)
Void, интересную штуку ты откопал. smile

Код

#include <list>

struct A
{
    std::list<struct B*> l; // компилится без проблем
};

int main()
{
A a;
}


А что это? В стандарте не нашел?

А что тут странного. Обычная фишка языка. Компилятору всё-равно на что указатель, т.к. размер указателя для лубого класса имеет один и тот же размер. Суть в том, что толку от такой записи нет, если нет потом определения класса B.
PM MAIL WWW   Вверх
LPBOY
Дата 7.12.2005, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

Репутация: 20
Всего: 20



Так дело в том что B неопределен!!
Почему тогда так не компилится?

Код

#include <list>
struct A
{
    std::list<B*> l; 
};
int main()
{
A a;
}

--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
Daevaorn
Дата 7.12.2005, 15:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(LPBOY @ 7.12.2005, 15:09)
Так дело в том что B неопределен!!
Почему тогда так не компилится?

Код

#include <list>
struct A
{
    std::list<B*> l; 
};
int main()
{
A a;
}

Прально, В же не определен.
А по поводу предыдущего куска, ты же нигде в коде не используешь B. Поэтому и предварительное объявление class B вполне нормально, но бесполезно, т.к. разыменовать указатель на B у тебя не получится.
PM MAIL WWW   Вверх
Neitron
Дата 7.12.2005, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 580
Регистрация: 3.10.2005
Где: Москва

Репутация: 2
Всего: 5



LPBOY
Не забываем про существование объявлений.


--------------------
Хороший программист никогда ничего не делает хорошо с первого раза. Он понимает важность патчей.
Ⓘ ⓁⒾⓀⒺ ⓂⓄⓏⒾⓁⓁⒶ
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1207 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.