예 아니요 : 예 두 번 호출되고 두 개의 다른 개체에 대해 호출되지 않습니다.
의 요 때문에 A.cpp 및 B.cpp 모두 dfinitializer
의 로컬 및 독립적 인 복사본이됩니다 #INCLUDE의
// A.cpp
#include "datafile.h"
...
및
// B.cpp
#include "datafile.h"
...
있다고 가정 해 봅시다.
datafile.cpp가 차례로 nifty_counter
(초기 0 값 ... static int nifty_counter = 0;
)으로 정의하고 CDatafile :: mSome (파일 수준에서 초기화 됨)이 있습니다.
ctor는 mSome
에 이미 초기화되고 즉시 만들어지고 소멸되는 임시 CSomeClass()에 할당됩니다.
사실 CDataFile이 할당 가능하기 때문에 실제로 올바른 일을하는 잘못된 구현입니다.
정적 데이터 멤버를 초기화하는 데 문제가 있다면 정적 멤버 정의 (참고 : 정의가 아니라 선언)가 포함 된 모듈의 일부가 다른 부작용을 일으키는 다른 멤버에 의해 호출되는지 확인하면됩니다.
CDataFileInitializer[0x406035] creation
CDataFileInitializer FIRST INITIALIZATION
CSome[0x40602c] default created
initializing A.cpp
CDataFileInitializer[0x406029] creation
initializing B.cpp
CDataFileInitializer[0x406025] creation
main
do something in a.ccp
do something in b.ccp
main return
CDataFileInitializer[0x406025] destruction
cleaning B.cpp
CDataFileInitializer[0x406029] destruction
cleaning A.cpp
CSome[0x40602c] destroyed
CDataFileInitializer[0x406035] destruction
CDataFileInitializer LAST DESTRUCTION
,369 : 모듈이의 다음과 같은 출력을 줄 것이다 더 나은 트릭
//some.h
#ifndef SOME_H_INCLUDED
#define SOME_H_INCLUDED
#include<iostream>
class CSome
{
public:
CSome() { std::cout << "CSome["<<this<<"] default created" << std::endl; }
CSome(const CSome& s) { std::cout << "CSome["<<this<<"] created from ["<<&s<<"]" << std::endl; }
CSome& operator=(const CSome& s) { std::cout << "CSome["<<this<<"] assigned from ["<<&s<<"]" << std::endl; return *this; }
CSome(CSome&& s) { std::cout << "CSome["<<this<<"] created moving ["<<&s<<"]" << std::endl; }
CSome& operator=(CSome&& s) { std::cout << "CSome["<<this<<"] assigned moving ["<<&s<<"]" << std::endl; return *this; }
~CSome() { std::cout << "CSome["<<this<<"] destroyed" << std::endl; }
};
#endif // SOME_H_INCLUDED
//datafile.h
#ifndef DATAFILE_H_INCLUDED
#define DATAFILE_H_INCLUDED
#include "some.h"
class CDataFile
{
public:
protected:
static CSome mSome;
};
static class CDataFileInitializer
{
public:
CDataFileInitializer();
~CDataFileInitializer();
} datafileinitializer;
#endif // DATAFILE_H_INCLUDED
//datafile.cpp
#include "datafile.h"
#include <iostream>
static int nifty_counter = 0; //the one and only
CSome CDataFile::mSome; //define and initialize
CDataFileInitializer::CDataFileInitializer()
{
std::cout << "CDataFileInitializer["<<this<<"] creation"<< std::endl;
if(!nifty_counter++)
{
std::cout << "CDataFileInitializer FIRST INITIALIZATION"<< std::endl;
}
}
CDataFileInitializer::~CDataFileInitializer()
{
std::cout << "CDataFileInitializer["<<this<<"] destruction"<< std::endl;
if(!--nifty_counter)
{
std::cout << "CDataFileInitializer LAST DESTRUCTION"<< std::endl;
}
}
//A.cpp
#include <iostream>
static class A
{
public:
A() { std::cout << "initializing A.cpp" << std::endl; }
~A() { std::cout << "cleaning A.cpp" << std::endl; }
} a;
#include "datafile.h"
// other a.cpp code ...
void call_a() { std::cout << "do something in a.ccp" << std::endl; }
//B.cpp
#include <iostream>
static class B
{
public:
B() { std::cout << "initializing B.cpp" << std::endl; }
~B() { std::cout << "cleaning B.cpp" << std::endl; }
} b;
#include "datafile.h"
// other b.cpp code ...
void call_b() { std::cout << "do something in b.ccp" << std::endl; }
//main.cpp
#include <iostream>
void call_a();
void call_b();
int main()
{
std::cout << "main" << std::endl;
call_a();
call_b();
std::cout << "main return" << std::endl;
return 0;
}
를 해보자 ...
그래서 (그냥 최적화 할 피하기 위해)
코스 중 주소는 컴퓨터에 따라 변경되어 실행됩니다.
이것은 멋진 카운터가 아닙니다. 이것은 정의되지 않은 동작입니다. – Mankarse
@Mankarse : 정의되지 않은 이유를 설명해 주시겠습니까? –
'CSomeClass CDataFile :: mSome'의 동적 초기화는'dfinitializer'의 동적 초기화에 대해 불확실한 순서로 배열됩니다. 따라서'CDataFile :: mSome'에서'operator ='가 호출되면 아직 구성되지 않았을 수 있습니다. – Mankarse