생성자를 대신해 static 함수로 객체를 생성하려 합니다.

greathero의 이미지

class Scard: public Card { 
public: 
	// static 함수로 객체를 생성해봅시다!
	static SCard& createCard(std::string name) {  // 첫번째 함수(참조자 리턴)
		static SCard(name); // 지역 static 객체 생성함
		return sc;
	}
 
	static SCard& createCard2(std::string name) {  // 두번째 함수(참조자 리턴)
		SCard sc = Scard(name); 
		return sc;
	}
 
	static SCard* createCard3(std::string name) {  // 세번째 함수(포인터 리턴)
		SCard* sc = new SCard(name);
		return sc;
	}
private:
	SCard(std::string name) { // 생성자와 소멸자는 private에 짱박아놓았습니다.
		stat = new Status(name);
		stat->printStatus();
	}
        ~SCard() { delete stat; }
	Status* stat;
};

SCard 타입의 인스턴스를 생성자를 사용하지 않고
createCard, createCard2, createCard3라는 static 함수를 이용하여 생성하려고 합니다.

createCard, createCard2는 에러가 나고 createCard3은 정상적으로 실행이됩니다.
대체 왜 createCard, createCard2는 에러가 날까요?

또한, createCard, createCard2에선 소멸자를 private에 놓으니 엑세스할 수 없다고 하는데 왜그런걸까요?

greathero의 이미지

createCard2는 당연히 안되겠군요.
함수안에서 선언된 지역 객체의 참조자를 리턴하니깐요ㅠ

createCard는 왜 안되고 createCard3는 왜 잘되는지는 아직 아리송하네요...

greathero의 이미지

왜 2번 호출이 되징-_-;;;

greathero의 이미지

그런데 어떻게 잘 돌아가는거지;;;

익명 사용자의 이미지

올려주신 클래스를 사용하는 코드를 올려주세요.
그래야 정확한 대답을 할 수 있습니다.
어쨌거나 일반적인 싱글톤 패턴은 createCard 입니다.

greathero의 이미지

SCard sc1 = SCard::createCard("Card1");
SCard sc2 = SCard::createCard2("Card2");
SCard* sc3 = SCard::createCard3("Card3");

sc1.cardInfo(); // 에러
sc2.cardInfo(); // 에러
sc3->cardInfo(); // 출력됨

익명 사용자의 이미지

1. 소멸자가 private이 아니라면

SCard sc1 = SCard::createCard("Card1");
이렇게 하면 sc1은 createCard가 반환한 객체를 복사 생성한 객체입니다.
따라서 sc1이 스코프에서 벗어나면서 소멸자가 호출되고,
프로그램이 종료할 때에 createCard가 생성한 static 지역 객체의 소멸자가 호출되게 됩니다.

SCard& sc1 = SCard::createCard("Card1");
처럼 사용하는 것이 아마도 원래 의도했던 것이겠지요.

그리고 new로 힙에 생성한 객체는 명시적으로 소멸자를 호출하기 전에는 메모리에 계속 살아있습니다.
createCard3에 의해 생성된 객체는 프로그램 종료시까지 계속 살아있고 당연히 소멸자는 호출되지 않습니다.
프로그램 종료 후에 어차피 OS가 메모리를 회수하기는 하지만 그래도 힙에 잡은 메모리는 명시적으로 해제해주는 것이 좋습니다.

2. 소멸자가 private인 경우

그런 클래스의 객체는 스택에 생성될 수 없습니다.
힙에만 생성할 수 있고, 그 클래스의 멤버 함수나 프렌드 함수를 통해서만 제거할 수 있습니다.

greathero의 이미지

덕분에 궁금했던게 시원하게 풀렸어요!

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.