LINUX.ORG.RU

vot potomu chto u tebya napisano
CVector3 CWorld::getResult....
vmesto
CVector3& CWorld::getResult....
tyi i ispolzuesh KDevelop.

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

> vot potomu chto u tebya napisano
> CVector3 CWorld::getResult....
> vmesto
> CVector3& CWorld::getResult....
> tyi i ispolzuesh KDevelop.

А ты хочешь сказать, что везде должно быть Type &link?
ну ну... "чудак человек"...
вот оно, как терь некоторые ущемленные (чем-то или/и кем-то) индивиды с некоторым знанием Си++ самовыражевываются.
жуй-то жуй, да не чавкай, а то "как вспомню, аж бесит" и
ложкой по лбу.



anonymous
()

"The Sun & The Rainfall" - чумовая песня. Прусь до сих пор.

anonymous
()

Во первых:
Вообще то этот класс CVectro3 очень маленкий, все его методы реализованы как inline, и для него переопределены почти все операторы. То есть можно испрользовать такую конструкцию:

CVector3 res = a + b;

и т.д
поэтому удобно работать не с указателем, а непосредственно с экземпляром класса. Так как он небольшой, быстрый и т.д, вполне допустимо передавать экземпляр класса через стек.
:))
Но самая главная причина почему я написал

CVector3 CWorld::getResult....

а не

CVector3 &CWorld::getResult....
та, что результирующий вектор нигде не хранится. Он создается в стеке вызываемой функции getResult....в таком виде:

return CVector3(v);

и если вернуть ссылку, то куда она спрашивается будет указывать?
То есть где гарантия, что область стека в которой был распределен этот класс уже не затерта? Например была вызвана второй раз та же функция, которая возвращает совсем другой результат. Я имею ввиду следующую конструкцию:

CVector3 &getResult(float x, float y, float z) {
return CVector3(x, y, z);
}

void test() {<br>
CVector3 v1 = getResult(0, 1, 2);
CVector3 v2 = getResult(1, 2, 3);
cout << v1 << endl;
}

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

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

Хотя вы могли иметь ввиду такую конструкцию:

CVector3 &getResult(float x, float y, float z) {
static CVector3 res(x, y, z);
return res;
}

ну тогда конечно да :))

Можно было конечно и так:

CVector3 *res = new CVector3(v);
return res;

Ну понятное дело и объявление изменится.
Так работать быстрее будет, так как будет возвращаться 4 байта, а не весь класс.

Всегда успеем переделать если будет тормозить :))

Это было во первых, а во вторых, что-то я не вижу связи между редактором и качеством программ. К вашему сведению я когда то использовал для этих целей mc-edit. Тут все таки добнее :)) Да к тому же хоть и я программирую в KDevelop-e, но такую ахинею как вы не несу. Так что, как говорится читайте лекции :))

А теперья я наеду, можно :))

Вы бы лучше русский язык настроили, чем советы давать, когда их не просят. Или Вы "чисто-программист", и не нуждаетесь в такой фигне?

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

Banshee
() автор топика

спасибо Banshee за подробную лекцию! И за то что показал ананимусу(не мне) ХУ ИC ХУ! :))

anonymous
()

Да нема за що. В смысле не за что:)).

Banshee
() автор топика

static так работать не будет. Если конечно не вывести присваивание этих самых x,y,z из инициализации. А в остальном все правильно - использовать ссылки надо только при наличие преаллокированных объектов (например при выборке объекта CVector из существующего массива) или юзать new и передавать указатель. Вот только непонятно при чем здесь компактность или инлайновость методов ? Ведь передаются только свойства объектов, в крайнем случае передается еще vtable, размер которой не зависит от размера метода. Тем более если все это inline, то методы не виртуальные. Ну а редактирует каждый в том, что нравится :).

timur
()

2timur:

Статик будет работать.
Дестрактор то не вызывается, а класс в таком случае находится не в стеке по моему :))

Вот пример:

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream.h>
#include <stdlib.h>
#include <string.h>

class Class {
char *name;
public:
Class(const char *arg) {
name = (char *)malloc(10);
memset(name, 0, 10);
strcpy(name, arg);
};

virtual ~Class() {
free(name);
};

char *getName() { return name; };
};

Class &getClass(const char *val) {
static Class cl(val);
return cl;
}

int main(int argc, char *argv[]) {
cout << "Hello, World!" << endl;

Class cl = getClass("Test");
Class cl1 = getClass("Test1");
cout << cl.getName() << endl;

return EXIT_SUCCESS;
}

А инлайновость методов действительно не причем :)). Я просто хотел сказать, что это хорошо (правильно) написанный класс.

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

Banshee
() автор топика

Я бы еще добавил для полноты картины, что указатель на экземпляр класса есть указатель на его таблицу виртуальных методов. Вот теперь наверное все :))

Banshee
() автор топика

Отлично :), только для полноты картины добавьте еще
cout << cl1.getName() << endl;
Таблица виртуальных функций(vtable) это набор указателей на виртуальные методы. В блоке памяти, на который указывает указатель на объект, хранятся свойства и vtable. Теперь подумайте что означает хранятся методы (это ваши слова) ? Хранится код методов в каждом объекте ? Зачем ? Код метода шарится между всеми экземплярами объекта данного класса (ведь он одинаков для всех), и при вызове метода по месту подставляются различные аргументы. Ведь адрес метода (не виртуального) это compile time информация (или, если угодно linking time). Ну а адрес виртуальных методов это в общем случае runtime информация и для них требуется еще разыменование указателя на функцию и, собственно, вызов ее.

timur
()

Вот блин достал. Нашел к чему придраться. Объясняет прописные истины с видом гуру.

Ясен пень, что в таблице виртуальных методов хранятся указатели. А вы что думали?

А на счет добавления
cout << cl1.getName() << endl;

Что то я не понял :)) Всеравно будет выведен "Test1".

В обоих случаях будет выведен "Test1" в стд.оут.

Banshee
() автор топика

Зачем так нервничать ? Вы добавили cout << cl1.getName() ? Будет выведено:
Test
Test
Еще раз повторяю: надо выводить присваивания из инициализации.
Class &getClass(const char *val) {
static Class cl;
cl = val;
return cl;
}
>> Ясен пень, что в таблице виртуальных методов хранятся указатели. А вы что думали?
Я так и думал, о чем и написал, а Вы написали так: "передается по моему только таблица виртуальных методов (так эта таблица называется). На самом деле в ней хранятся: свойства, методы и виртуальные методы." Никакие свойства, а тем более методы в ней не хранятся. Впрочем, если Вас это так сильно напрягает, то писать сюда я больше не буду. Все вопросы на timur@dezcom.mephi.ru

timur
()

Подвожу итог:

да, сразу скажу, что все это я попробовал, прежде чем писать.

если фукция будет описана таким образом,

Class &getClass(const char *val) {
Class cl(val);
return cl;
}

то код

Class cl = getClass("Test");
Class cl1 = getClass("Test1");
cout << cl.getName() << endl;
cout << cl1.getName() << endl;

два раза выведет "Test1"

если она будет

Class &getClass(const char *val) {
static Class cl(val);
return cl;
}

то код

Class cl = getClass("Test");
Class cl1 = getClass("Test1");
cout << cl.getName() << endl;
cout << cl1.getName() << endl;

два раза выведет "Test"

если код будет такой
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream.h>
#include <stdlib.h>
#include <string.h>

class Class {
char *name;
public:
Class() {};
Class(const char *arg) {
name = (char *)malloc(10);
memset(name, 0, 10);
strcpy(name, arg);
};

virtual ~Class() {
free(name);
};

char *getName() { return name; };

void setName(const char *arg) { name = (char *)realloc((void *)name, strlen(arg) + 1); strcpy(name, arg); };
};

Class &getClass(const char *val) {
static Class cl;
cl.setName(val);
return cl;
}

int main(int argc, char *argv[]) {
Class cl = getClass("Test");
Class cl1 = getClass("Test1");
cout << cl.getName() << endl;
cout << cl1.getName() << endl;

return EXIT_SUCCESS;
}
то выведется два раза "Test1"

Что же до спора о таблице виртуальных методов, то дело обстоит так:
Указатель на экземпляр класса указывает на некую таблицу, в которой хранятся указатели на поля класса и на его методы (не виртуальные). Естественно есть и vtable, в которой хранятся указатели на все виртуальные методы класса. Именно в таком порядке. Сначала поля, а потом методы. Причем без разницы как описать поля (как указатели или как массив например). Только указывают они в разные места. (на область памяти в куче или в сегменте данных соотвестсвенно)

То есть Тимур полностью оказался прав. Публично это признаю. :))

Поля и методы действительно хранятся отдельно от виртуальных методов. А в таблице виртуальных методов хранятся только виртуальные методы. Если кто сомневается слобайте простенький класс без единого виртуального метода и посмотрите в отладчике.

Фух...

Banshee
() автор топика

Myisli v sluh

Sorry for slow reply.
2 Banshee :
Hochu srazu skazat, chto ya tak uzhasno programmyi ne pishu. Mne
hotelos proverit to, chto napisal Banshee.
/home/anonymous > cat a.cpp
#include <iostream>
class B {
public:
B(char* val){ value = val; };
char* value;
B& get(char*);
};
B& B::get( char* val )
{
return B(val);
}
main(int argc, char**argv)
{
B a("AAA");
B b = a.get("BBB");
B c = a.get("CCC");
cout << b.value << "\t" << c.value << endl;
}
/home/anonymous > g++ a.cpp
a.cpp: In method `class B & B::get(char *)':
a.cpp:10: warning: initialization of non-const reference `class B &' from rvalue `B'
a.cpp:10: warning: returning reference to temporary
/home/anonymous > ./a.out
BBB CCC

Nu i v chem u tebya problema? Tyi voobshe kakim kompilyatorom
polzueshsya i s kakimi nastroikami, lubitel CHAR* i malloc? Ya
ispolzoval egcs-2.91.66.

Po povodu moego vyiskazyivaniya :
ya vsego lish hotel spodvignut tebya na ispolzovanie udobnoi,
na moi i neslolkih millionov ludei vzglyad, sredyi programmirovaniya:
vi ili emacs ( XEmacs ya dumau tebe bolshe ponravitsya, cenitel
grafiki ), gmake ( ne nado kusatsya :), ya vizhu chto on tam
u tebya est ), cvs, shell. Eto ochen prosto, udobno i tyi ni k
chemu ne privyazan.

Po povodu russkogo : netu u menya russkoi klavyi, netu.

2 anonymous ( drugoi )
>спасибо Banshee за подробную лекцию! И за то что показал ананимусу(не мне) ХУ ИC ХУ! :))
Vrezh emu, vrezh ... :))). Sidi tukan', dyatel!

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