LINUX.ORG.RU

class A {
private:
  A(){}
  ~A(){}
  friend A* create_A(){return new A;}
  friend void delete_A(A* a){delete a;}
};

//class B:public A{
//public:
//  B(){}
//};

int main()
{
  A* a=create_A();
  delete_A(a);
  return 0;
}

PS
раскоментируй B

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

ну, если не мудрить с конструкторами А (не добавлять публичных), то деструктор можно сделать публичным (будет красивее ;) ).

k_andy ★★★
()

Если разговор идет о С++.NET, то если заглянуть в Managed Extensions for C++ Programming

то можно найти такое расширение __sealed

подходит?

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

class not_base {
friend class class_a;
private:
not_base() {}
};

class class_a : public virtual not_base {
public:
};

class class_b : public class_a { };


int main()
{
class_a a;
class_b b; // Not work

return 0;
}

aton
()

Наследование - одно из основополагающих ООПа. Кому может понадобиться создавать класс, от которого низя унаследосаться???

bugmaker ★★★★☆
()
Ответ на: комментарий от bugmaker

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

Ударенным на голову Java-программёрам.

По теме:

class A
{
private:
  A();
public:
  A( const A& );
  ~A();
  static A create();
}

int main()
{
  A a = A::create();
}

watashiwa_daredeska ★★★★
()
Ответ на: комментарий от aton

>Минус твоего решения - нельзя создовать объекты на стеке

Это не проблема.

#include <new>

class A{
private:
  A(){}
public:
  ~A(){}
  static A* create(){return new A;}
  static A* create(void* buf){return new(buf) A;}
};

template<class X> class auto_destroy{
public:
  auto_destroy(X* p):ptr(p){}
  ~auto_destroy(){ptr->~X();}
  operator X*(){return ptr;}
  X* operator ->(){return ptr;}
private:
  auto_destroy(){}
  auto_destroy(const auto_destroy<X>&){}
  auto_destroy<X>& operator=(const auto_destroy<X>&){return *this;}
  X* ptr;
};

int main()
{
  char buf[sizeof(A)];
  auto_destroy<A> ad(A::create(buf));
}

>в таком виде код не компилится

В твоем компилится. Не понимаю для чего нужен класс, объект которого
нельзя создать?

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

Пока и так имеется :) Но все равно спасибо

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

Опять бред:

- Для каждого конструктора придется писать аналогичный
вариант create, модно конечно обобщить, но в
данном случае это изврат

По поводу auto_destroy:

private:
auto_destroy<X>& operator=(const auto_destroy<X>&){return *this;}

Зачем?

~auto_destroy(){ptr->~X();}
не приведет к освобождению памяти

и т.д.

вообщем не очень умный указатель получился, возможно стоит
посмотреть в сторону boost::scope_ptr


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

> Не понимаю для чего нужен класс, объект которого нельзя создать?
Бывают случаи, например клнтейнеры из STL :) Правда там все только
на словах

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

еще вариация на тему, using CRTP.

template<class Derived> class sealed_base {
	// template friends workaround
	struct friender {
		typedef Derived type;
	};

	friend class friender::type;

	sealed_base() {}
};

struct sealed_class : virtual public sealed_base<sealed_class> {};

struct sealed_child_class : public sealed_class {};

int main() {

	sealed_class s;

	sealed_child_class child; // compile-time error

	return 0;
}

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

>- Для каждого конструктора придется писать аналогичный >вариант create, модно конечно обобщить, но в >данном случае это изврат

можно забабахать через boost::in_place_factory/typed_in_place_factory, правда все же изврат :)

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

с каких это пор для non-dependent names пишется typename ?

этот workaround работает, кстати, только для gcc у меня, для интела не работает, даже с typename :)

а если вот так:
- friend class friender::type;
+typedef friender::type friend_type;
+friend friend_type;

то работает для icc, и не работает для gcc :)

т.к. templated friends запрещены стандартом, то в каждом компиляторе workaround свой, если он вообще есть.

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

comeau вообще не пропускает ни в каком варианте код, хотя юзает тот же фронтент EDG, что и icc.

обломс :)

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

template<class Derived> class sealed_base {
protected:
	sealed_base() {}
};

struct sealed_class : virtual private sealed_base<sealed_class> {};

struct sealed_child_class : public sealed_class {};

int main() {

	sealed_class s;

//	sealed_child_class child; // compile-time error

	return 0;
}

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

Еще проще :)


class sealed_base
{
protected:
sealed_base() {}
};

struct sealed_class : virtual private sealed_base
{};

struct sealed_child_class : public sealed_class
{};

int main() {

sealed_class s;

sealed_child_class child; // compile-time error

return 0;
}

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

такое решение недостаточно параноидально. Помниться под билдером (на виндах) чего то я мутил такое свое... и у базового класса виджетовского какие то поля/методы были протектед, типа токо для наследников. Ну пришлось залезть в нидер и перенести это шаловливыми рученками в паблик секцию. "Можно придумать защиту от дурака, но только от неизобритательного"

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

AIv ★★★★★
()
Ответ на: комментарий от aton

>Опять бред:

Видимо я что-то пропустил в развитии плюсов. Будьте любезны - накидайте ссылок на литературу.

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