Рейтинг


Вопрос-Ответ (C++)
[1] Kornival [04 Сентября 2011, 19:10]
Чтобы не создавать отдельную тему на каждый глупый вопрос, предлагаю задавать их здесь.

Saitei: все вопросы по С задаём в теме Вопрос-Ответ (С). Благодарю за внимание!
[1241] goldsphere [19 Апреля 2014, 11:43]
bool ClassName::isTrue(){}
[1242] danielskachkov [19 Апреля 2014, 12:04]
И еще одно, с Вашего позволения. Правда ли, что тип функции virtual нужно указывать только в h-файле? То есть в h-файле я пишу: virtual bool isTrue(), а в срр-файле: bool ClassName::isTrue() {...}.
[1243] goldsphere [19 Апреля 2014, 12:17]
danielskachkov, да
А в чём проблема проверить? Или хотя бы прочитать немного об этом?


Сообщение отредактировал goldsphere - Суббота, 19 Апреля 2014, 12:18
[1244] danielskachkov [19 Апреля 2014, 13:41]

Добавлено (19.04.2014, 13:41)
---------------------------------------------
В чем смысл этого выражения:
IDFlag_IsPickable = 1 << 0
Никак не возьму в толк. Ведь если я все правильно понял, 1 << 0 == 1 * 2^0, то есть 1 * 1 (так как 2 в нулевой степени равняется 1).

[1245] OpenGOO [19 Апреля 2014, 14:20]
Цитата danielskachkov ()
И еще одно, с Вашего позволения. Правда ли, что тип функции virtual нужно указывать только в h-файле? То есть в h-файле я пишу: virtual bool isTrue(), а в срр-файле: bool ClassName::isTrue() {...}.


Когда ты пишешь так:

foo.h

Код
#pragma once

class Foo
{
public:
    virtual bool isTrue();
}


foo.cpp

Код
#include "foo.h"

bool Foo::isTrue() {...}


то конечный код после работы препроцессора становится вот таким

foo.cpp

Код
class Foo
{
public:
    virtual bool isTrue();
}

bool Foo::isTrue() {...}


Сообщение отредактировал OpenGOO - Суббота, 19 Апреля 2014, 14:23
[1246] -l33t-h4xx- [19 Апреля 2014, 15:22]
Цитата danielskachkov ()
IDFlag_IsPickable = 1 << 0

Выражение действительно не имеет смысла с точки зрения программы, скорее всего это напоминание для программиста, что нулевой бит некой переменной является флажком, отвечающим за свойство IsPickable. Не удивлюсь, если там рядом есть и такие определения:
Код
const int IDFlag_IsPickable = 1 << 0;
const int IDFlag_IsPackable = 1 << 1;
const int IDFlag_IsPokable = 1 << 2;
const int IDFlag_IsWhateverYouWant = 1 << 3;


Сообщение отредактировал -l33t-h4xx- - Суббота, 19 Апреля 2014, 15:27
[1247] danielskachkov [19 Апреля 2014, 21:38]
Прошу прощения за назойливость, хочу уж сразу добить все неясности. Насколько я понял, все сторонние "инклуды" следует подключать в .h-файле, а в .срр только сам .h-файл класса. По крайней мере, подобная конструкция вполне работает. И еще. Я где-то читал (на одном из форумов), что все заголовочные файлы, подключаемые выше заголовочного файла нашего класса, автоматически подключаются и к нему. Пример:
Код
#include <iostream>
#include <vector>
#include <...>
#include "MyClass.h"

Действительно ли все эти библиотеки будут подключены к моему классу? В моем коде это почему-то не работало.
[1248] -l33t-h4xx- [20 Апреля 2014, 14:17]
Цитата danielskachkov ()
Насколько я понял, все сторонние "инклуды" следует подключать в .h-файле,

Лучше всё же обойтись только теми заголовочниками, без которых класс не будет работать. Это, помимо всего прочего, документирует зависимости, в будущем ты будешь ценить такую возможность: программы станут большими, лишние инклуды неизбежно вызовут головную боль.

Насчёт инклуда вообще: директива #include "имя-файла" только и делает, что вставляет на место себя содержимое указанного файла, никакие библиотеки он на самом деле не подключает. Советую почитать на темы "компиляция" и "препроцессор", большинство вопросов отпадёт (хотя бы здесь и здесь).


Сообщение отредактировал -l33t-h4xx- - Воскресенье, 20 Апреля 2014, 14:23
[1249] goldsphere [20 Апреля 2014, 15:49]
danielskachkov, смотри, ты подключаешь либы в то место где они тебе нужны, если ты хочешь в объявлении класса их использовать то да, подключаешь туда, например
#include <vector>

class A{
std::vector<Objects> vec;
}

если там они тебе не нужны, а нужны только в теле методов класса, то лучше подключать к cpp файлу. Бывают ситуации, когда происходит зацикливание подключений.


Сообщение отредактировал goldsphere - Воскресенье, 20 Апреля 2014, 15:49
[1250] -l33t-h4xx- [21 Апреля 2014, 11:46]
Цитата goldsphere ()
Бывают ситуации, когда происходит зацикливание подключений.

Это когда? Мне правда интересно, я с таким не сталкивался (если ты не о забытой ifndef-защите, конечно).
[1251] OpenGOO [21 Апреля 2014, 13:45]
Может имелся в виду этот случай

foo.h

Код
#ifndef FOO_H
#define FOO_H

#include "bar.h"

class Foo
{
       public:
           Foo(Bar *bar)
           {
               _bar = bar;
               _bar->setFoo(this);
           }
           virtual ~Foo() {}

       private:
           Bar* _bar;
};

#endif // FOO_H


bar.h

Код
#ifndef BAR_H
#define BAR_H

#include "foo.h"

class Bar
{
       public:
           virtual ~Bar() {}

           void setFoo(Foo *foo) { _foo = foo; }

       private:
           Foo* _foo;
};

#endif // BAR_H


Сообщение отредактировал OpenGOO - Понедельник, 21 Апреля 2014, 16:45
[1252] GameMix [11 Мая 2014, 18:46]
Здравствуйте! С постепенным выделением памяти с помощью new и без встроенных структур данных C++ почти разобрался. Программа теперь не вылетает, но при определенном количестве динамически добавленных элементов в массив вывод их значений на экран перестаёт работать.
Вот код:
Код
#include <iostream>
using namespace std;

int main()
{
int *a = new int;
int i = 0, count, number;

do
   {
    cin >> number;
    if (number == 0) continue;
    a[i] = *new int;
    a[i] = number;
    i ++;
   }
while (number != 0);

count = i;

for (i = 0; i < count; i ++) cout << a[i] << ' ';

return 0;
}

Прошу помощи smile
[1253] Saitei [11 Мая 2014, 21:19]
GameMix,
Код
int *a = new int;
int i = 0, count, number = 0;

do
    {
     number++;
     if (number == 100500) continue;
     a[i] = *new int;
     a[i] = number;
     i ++;
    }
while (number != 100500);

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

И, насколько я знаю, чтобы добавить новый элемент в динамичееский массив Q, надо создать второй массив и скопировать туда массив, потом для Q выделить память на единицу больше, чем раньше, скопировать со второго массива и в самый конец засунуть новый элемент. По крайней мере так я понимаю работу того же std::vector. Могу ошибаться
[1254] OpenGOO [12 Мая 2014, 00:25]
Сперва надо создать массив, например на 256 элементов
Код
int *a = new int[256];


Вот эта строка вообще ненужна
Код
a[i] = *new int;


GameMix, ты вообще по какой книге язык изучаешь?

Что ты этим
Код
if (number == 0) continue;
хотел добиться?

Если не понимаешь как работает код, то делай трассировку.
[1255] Storm54 [12 Мая 2014, 00:29]
Цитата
И, насколько я знаю, чтобы добавить новый элемент в динамичееский массив Q, надо создать второй массив и скопировать туда массив, потом для Q выделить память на единицу больше, чем раньше, скопировать со второго массива и в самый конец засунуть новый элемент. По крайней мере так я понимаю работу того же std::vector. Могу ошибаться

Никогда не смотрел исходники стандартных контейнеров, но что-то мне подсказывает, что там каждый объект представляет из себя структуру, похожую на эту:

Код

struct Object
{
   T current;
   Object* next;
};


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


Сообщение отредактировал Storm54 - Понедельник, 12 Мая 2014, 00:30
[1256] OpenGOO [12 Мая 2014, 01:20]
Кто-то не знает чем массив отличается от списка
[1257] goldsphere [12 Мая 2014, 07:18]
OpenGOO, массив это просто набор не связанных между собой элементов. Всё что можно делать с массивом это получить элемент по индексу. Список - это класс, где каждый элементы между собой связаны, указывают друг на друга. В списке нельзя получить доступ к элементу по индексу, доступ к элементам может быть только последовательным
[1258] GameMix [12 Мая 2014, 07:45]
Цитата OpenGOO ()
int *a = new int[256];

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

Пользователь вводит по одному числу до тех пор, пока не введёт число 0. 0 означает завершение ввода чисел в массив. Так вот, если юзер не поленится и введёт более 256 чисел, то дальше запись пойдёт фиг знает в какие адреса, и работать с теми числами будет, как минимум, проблематично.

Storm54, интересный вариант, попробую сделать так. Но всё равно странно, ведь с массивом тоже можно было бы сделать около 1000 постепенно выделяемых ячеек памяти под элементы массива.
[1259] last2424 [12 Мая 2014, 07:48]
GameMix, а обнулять при определённом количестве не пробовал?
[1260] Storm54 [12 Мая 2014, 07:59]
нельзя сделать постепенно выделяемый массив. В некоторых случаях это аппаратно невозможно. Так что я вижу единственный вариант решения проблемы - тот, который я описал выше.