> vot potomu chto u tebya napisano
> CVector3 CWorld::getResult....
> vmesto
> CVector3& CWorld::getResult....
> tyi i ispolzuesh KDevelop.
А ты хочешь сказать, что везде должно быть Type &link?
ну ну... "чудак человек"...
вот оно, как терь некоторые ущемленные (чем-то или/и кем-то) индивиды с некоторым знанием Си++ самовыражевываются.
жуй-то жуй, да не чавкай, а то "как вспомню, аж бесит" и
ложкой по лбу.
Во первых:
Вообще то этот класс 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);
}
Как вы думаете, что выведется в стд.оут. содержимое первого вектора или второго?
То есть то что вы предлагаете, это оставлять в уже освобожденном стеке данные, которые когда то будут может быть получены, а может быть и запорчены.
Больше того, если вы потом будете использовать где-то 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, но такую ахинею как вы не несу. Так что, как говорится читайте лекции :))
А теперья я наеду, можно :))
Вы бы лучше русский язык настроили, чем советы давать, когда их не просят. Или Вы "чисто-программист", и не нуждаетесь в такой фигне?
А что до вашего заявления, то сделайте тростенький примерчик и убедитесь сами.
static так работать не будет. Если конечно не вывести присваивание этих самых x,y,z из инициализации. А в остальном все правильно - использовать ссылки надо только при наличие преаллокированных объектов (например при выборке объекта CVector из существующего массива) или юзать new и передавать указатель. Вот только непонятно при чем здесь компактность или инлайновость методов ? Ведь передаются только свойства объектов, в крайнем случае передается еще vtable, размер которой не зависит от размера метода. Тем более если все это inline, то методы не виртуальные. Ну а редактирует каждый в том, что нравится :).
Class cl = getClass("Test");
Class cl1 = getClass("Test1");
cout << cl.getName() << endl;
return EXIT_SUCCESS;
}
А инлайновость методов действительно не причем :)). Я просто хотел сказать, что это хорошо (правильно) написанный класс.
А на счет того что передается, то передается по моему только таблица виртуальных методов (так эта таблица называется). На самом деле в ней хранятся: свойства, методы и виртуальные методы. По моему так :))
Отлично :), только для полноты картины добавьте еще
cout << cl1.getName() << endl;
Таблица виртуальных функций(vtable) это набор указателей на виртуальные методы. В блоке памяти, на который указывает указатель на объект, хранятся свойства и vtable. Теперь подумайте что означает хранятся методы (это ваши слова) ? Хранится код методов в каждом объекте ? Зачем ? Код метода шарится между всеми экземплярами объекта данного класса (ведь он одинаков для всех), и при вызове метода по месту подставляются различные аргументы. Ведь адрес метода (не виртуального) это compile time информация (или, если угодно linking time). Ну а адрес виртуальных методов это в общем случае runtime информация и для них требуется еще разыменование указателя на функцию и, собственно, вызов ее.
Зачем так нервничать ? Вы добавили cout << cl1.getName() ? Будет выведено:
Test
Test
Еще раз повторяю: надо выводить присваивания из инициализации.
Class &getClass(const char *val) {
static Class cl;
cl = val;
return cl;
}
>> Ясен пень, что в таблице виртуальных методов хранятся указатели. А вы что думали?
Я так и думал, о чем и написал, а Вы написали так: "передается по моему только таблица виртуальных методов (так эта таблица называется). На самом деле в ней хранятся: свойства, методы и виртуальные методы." Никакие свойства, а тем более методы в ней не хранятся. Впрочем, если Вас это так сильно напрягает, то писать сюда я больше не буду. Все вопросы на timur@dezcom.mephi.ru
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, в которой хранятся указатели на все виртуальные методы класса. Именно в таком порядке. Сначала поля, а потом методы. Причем без разницы как описать поля (как указатели или как массив например). Только указывают они в разные места. (на область памяти в куче или в сегменте данных соотвестсвенно)
То есть Тимур полностью оказался прав. Публично это признаю. :))
Поля и методы действительно хранятся отдельно от виртуальных методов. А в таблице виртуальных методов хранятся только виртуальные методы. Если кто сомневается слобайте простенький класс без единого виртуального метода и посмотрите в отладчике.
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!