LINUX.ORG.RU

#include <iostream>

class A { public: static void hi() { cout<<"hello, ignite. Say thanks ;-)"<<endl; }; };

int main (int argc, char * argv[]) { A::hi(); }; //main

anonymous
()

Используй static при описании метода.

anonymous
()

Уфф, спасибо огромное, а то я почти веру в С++ потерял :)
Главное, что статик догадался (по логике вещей), только писал
вызов как test.read(1), компилер ругался. А про двоеточия 
мне в голову не пришло, начал уже workaround делать :).
Хотелось собственно вот такого кода - типа чтения из потока:

------------------------------------------------------------
class test
{
	int data;
public:
	test(){ data = 0; };
	test(int a){ data = a; };

	static test *read(int a)
	{ 
		if( a>0 )
		{
			return new test(a);
		} else return NULL; 
	}
};

int main(int argc, char* argv[])
{
	test *t;
	
	if( (t = test::read(1)) != NULL)
		printf("Read OK\n");
	else
		printf("Read failed!\n");
	return 0;
}
-------------------------------------------------------

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

Кстати, смежный вопрос :) что нужно написать в конструкторе, чтобы new вернул NULL ? Типа выделяем в конструкторе память, если облом, то как сказать, чтобы верхний new тоже выдал облом (или лучше пример с файлом, т.к. с памятью это и так случится :)

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

2 gnite:
Выделять память в конструкторе это ошибка, если передаёшь string как параметер то делай так:
#include <iostream>
using namespace std;
class A
{
public:
	A(char* str):m_str(str){}
	~A(){}
	char* m_str;
	void printStr(){cout<<m_str<<endl;}
};

int main()
{
	A a("string");
	a.printStr();
	return 0;
}

anonymous
()

Ooops popravka :-))

#include <iostream>
using namespace std;
class A
{
public:
	A(char* str):m_str(str){}
	~A(){}
	void printStr(){cout<<m_str<<endl;}
private:
	char* m_str;
};

int main()
{
	A a("string");
	a.printStr();
	return 0;
}

anonymous
()

2 anonymous (*) (2002-05-30 03:25:32.681) Ню-ню... А потом спрашивают: "отчего же у меня программа падает?" Данные, которые использует экземпляр класса, нужно хранить локально (за исключением специальных случаев, но это другой разговор). Выделение памяти в конструкторе часто - необходимость, т.к. тот кто будет использовать твой класс не должен городить огород типа MyClass obj; obj.init (); - для инициализации класса. Это неудобно, да и забыться можно.

2 ignite К сожалению, NULL вернуть нельзя. Можно только сгенерить exeption, который потом перехватить:

class A { public: A () { // что нибудь делаем ... if (errors) throw "error in constructor"; } }

А вообще, по этому вопросу, лучше проштудировать Страуструпа.

romanSA
()

Совершенно одобрямс romanSA. Инициализация члена класса (указателя)
другим указателем наводит на плохие мысли, особенно если потом этот
указатель разименовывается. Кстати следует обратить внимание на STL -
там фокусов с памятью нет. Если нужно поработать со строками - лучше
уж в качестве типа члена класса исопользовать string (из STL)
А обработку неудачного выделения памяти можно сделать так:

try
{
MyClass a(.....); // в конструкторе есть операторы new
a.some_method(....); // используются члены класса, инициализированные new, если они все еще NULL, то "выбросить" исключение
.....
}
catch(.......)
{
}

PETER ★★
()

2ignite

На мой взгляд конструкции типа:
>int main(int argc, char* argv[])
>{
> test *t;
....
>t = test::read(1);

лучше вообще избегать, так как не понятно кто будет вызывать delete.
Да и потом замучаешся искать где память течет и что вызывает
segmentation fault

Можно было бы использовать в простых случаях
auto_ptr<test> t(test::read(1));
А в более сложных нужно смастерить "smart pointer" со встроенным
(в test) счетчиком.

К сожалению auto_ptr мне так и не удалось засунуть в какой-нибудь
стандартный контейнер :-(, а было бы не плохо.
Может кто-нибудь знает как это делается ?

anonymous
()

2 anonymous (*) (2002-05-31 14:05:30.216)
Насчёт auto_ptr в контейнере: очень стрёмная штуковина.
Дело в том, что этот шаблон устроен примерно так (в разных _реализациях_ STL м.быть по-разному но везде суть одна):
template <class Tptr> auto_ptr
{
...
private:
bool Owns;
Tptr * ptr;
}

Член Owns определяет, является ли экземпляр реализации шаблона владельцем указателя на данные ptr. Если да, то при уничтожении этого объекта будет освобождён и указатель.
Такая вот простота (+ реализация) приводят к тому, что при передаче объекта, созданного с применением auto_ptr в функцию "по значению", владельцем данных становится именно копия, переданная в функцию.
В результате после выхода из функции данные удаляются и исходным объектом уже не попользуешся.

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