B
Bryan Parkoff
I have C++ Primer Third Edition -- Author Stanley B. Lippman and Josee
Lajoie. I have been studying it for couple months however it does not
provide a valuable information which it is about "friend to class". I am
very disappointed because it is the way how C++ Compiler is designed. I
assume that "friend to class" is not the good option.
If CMain class is initialized before CA class, CB class, and CC class
are initialized inside CMain class' constructor function. It is like m_pCA
= new CA(this). I suspect that it is not a good idea because it might can
leak memory because it is not in the right order. I must manually order to
allocate and deallocate m_pCA myself. It can misled to a minor bug under
class design.
I have mentioned about the nested class, but it is not a good option.
The declaration and definition must be done before nested class can be used.
It can be a problem if I want to have only one class each header file
instead of two or more classes each header file.
I have decided to create multiple inheritance. All CA class, CB class
and CC class can be derived into one CMain class. All functions including
Constructor function and Destructor function are protected rather than
public because I do not allow CA class, CB class, and CC class to be
initialized under void main(void) function unless CMain class has authority
to access CA class, CB class, and CC class.
I can be able to show A.h, B.h, C.h, CMain.h, A.cpp, B.cpp, C.pp, and
CMain.cpp files. Four are headers and another fours are sources. CMain.h
can include A.h, B.h, and C.h while main.cpp can include CMain.h. It is
really a good class design.
I have decided to allow CA class, CB class, and CC class to share one
memory address that contains 10,000 elements in this array. CC class is the
one to allocate and deallocate m_pMem while CA class and CB class do not.
It is done automatically by Constructor function, otherwise, it can be done
manually by Initialize function.
How can CA class and CB class access CC class' m_pMem? I did not want
CA class and CB class to access CC class' m_pMem in order to modify 10,000
elements because it can slow the performance. It would be better to access
m_pMem inside CA class and CB class only. I have decided to use Get_Mem
function and Set_Men function to copy memory address (4 bytes) from CC
class' m_pMem to CA class' and CB class' m_pMem. All three classes' m_pMem
are always private. I do not want to accidently overwrite m_pMem such as
CA::m_pMem = CC::m_pMem. Set_Mem function and Get_Mem function are useful
to prevent from overwritten accidently.
The problem is that m_pMem can't be deallocated two times or three
times, but it must be done once, otherwise, it can leak memory. It is why I
have to use Terminate function to deallocate m_pMem manually inside CMain
class rather than Destructor function inside CA class, CB class, and CC
class. Look at Destructor example below.
CA:estructor()
{
if (m_pMem != NULL)
delete [] m_pMem;
}
CB:estructor()
{
if (m_pMem != NULL)
delete [] m_pMem;
}
CC:estructor()
{
if (m_pMem != NULL)
delete [] m_pMem;
}
CC:estructor() will be executed first to detect m_pMem before it can
deallocate safely however CB:estructor() and CA:estructor() will fail,
because they think that m_pMem is NOT ALREADY deallocated before they
attempt to deallocate second time. It would be safe to put m_pMem = NULL in
both CA:estructor() and CB:estructor(), otherwise Terminate() can be
used in CMain class only.
Please provide a safe method to deallocate shared memory from three
classes. I have included my simple source code below. Please mention what
you think about my class design which is neat and better design. Please
advise.
Please note: Multiple Inheritance only allow protected functions rather
than public functions that I have chosen. Only void main(void) function is
allowed to access CMain::Run(), but it is not allowed to access all
functions inside four classes. CMain::Run() is the one that it has
authority to access ALL PROTECTED functions in three classes. Does it make
sense?
#include <stdio.h>
class CA
{
protected:
CA()
{
printf("CA Constructor\n");
}
~CA()
{
printf("CA Deconstructor\n");
}
void Run(void)
{
printf("CA Run\n");
}
unsigned char* Get_Mem(void)
{
return m_pMem;
}
void Set_Mem(unsigned char* pMem)
{
m_pMem = pMem;
}
private:
CA(const CA& rA);
CA& operator=(const CA& rA);
unsigned char* m_pMem;
};
class CB
{
protected:
CB()
{
printf("CB Constructor\n");
}
~CB()
{
printf("CB Deconstructor\n");
}
void Run(void)
{
printf("CB Run\n");
}
unsigned char* Get_Mem(void)
{
return m_pMem;
}
void Set_Mem(unsigned char* pMem)
{
m_pMem = pMem;
}
private:
CB(const CB& rB);
CB& operator=(const CB& rB);
unsigned char* m_pMem;
};
class CC
{
protected:
CC()
{
printf("CC Constructor\n");
m_pMem = new unsigned char[0x10000];
}
~CC()
{
printf("CC Deconstructor\n");
delete [] m_pMem;
}
void Run(void)
{
printf("CC Run\n");
}
unsigned char* Get_Mem(void)
{
return m_pMem;
}
void Set_Mem(unsigned char* pMem)
{
m_pMem = pMem;
}
private:
CC(const CC& rC);
CC& operator=(const CC& rC);
unsigned char* m_pMem;
};
class CMain : public CA, public CB, public CC
{
public:
CMain()
{
printf("CMain Constructor\n");
Initialize();
}
~CMain()
{
printf("CMain Deconstructor\n");
Terminate();
}
void Run(void)
{
printf("CMain Run\n");
CA::Run();
CB::Run();
CC::Run();
}
private:
void Initialize(void)
{
CA::Set_Mem(CC::Get_Mem());
CB::Set_Mem(CC::Get_Mem());
}
void Terminate(void)
{
CA::Set_Mem(NULL);
CB::Set_Mem(NULL);
}
CMain(const CMain& rMain);
CMain& operator=(const CMain& rMain);
};
void main(void)
{
CMain Main;
Main.Run();
}
Lajoie. I have been studying it for couple months however it does not
provide a valuable information which it is about "friend to class". I am
very disappointed because it is the way how C++ Compiler is designed. I
assume that "friend to class" is not the good option.
If CMain class is initialized before CA class, CB class, and CC class
are initialized inside CMain class' constructor function. It is like m_pCA
= new CA(this). I suspect that it is not a good idea because it might can
leak memory because it is not in the right order. I must manually order to
allocate and deallocate m_pCA myself. It can misled to a minor bug under
class design.
I have mentioned about the nested class, but it is not a good option.
The declaration and definition must be done before nested class can be used.
It can be a problem if I want to have only one class each header file
instead of two or more classes each header file.
I have decided to create multiple inheritance. All CA class, CB class
and CC class can be derived into one CMain class. All functions including
Constructor function and Destructor function are protected rather than
public because I do not allow CA class, CB class, and CC class to be
initialized under void main(void) function unless CMain class has authority
to access CA class, CB class, and CC class.
I can be able to show A.h, B.h, C.h, CMain.h, A.cpp, B.cpp, C.pp, and
CMain.cpp files. Four are headers and another fours are sources. CMain.h
can include A.h, B.h, and C.h while main.cpp can include CMain.h. It is
really a good class design.
I have decided to allow CA class, CB class, and CC class to share one
memory address that contains 10,000 elements in this array. CC class is the
one to allocate and deallocate m_pMem while CA class and CB class do not.
It is done automatically by Constructor function, otherwise, it can be done
manually by Initialize function.
How can CA class and CB class access CC class' m_pMem? I did not want
CA class and CB class to access CC class' m_pMem in order to modify 10,000
elements because it can slow the performance. It would be better to access
m_pMem inside CA class and CB class only. I have decided to use Get_Mem
function and Set_Men function to copy memory address (4 bytes) from CC
class' m_pMem to CA class' and CB class' m_pMem. All three classes' m_pMem
are always private. I do not want to accidently overwrite m_pMem such as
CA::m_pMem = CC::m_pMem. Set_Mem function and Get_Mem function are useful
to prevent from overwritten accidently.
The problem is that m_pMem can't be deallocated two times or three
times, but it must be done once, otherwise, it can leak memory. It is why I
have to use Terminate function to deallocate m_pMem manually inside CMain
class rather than Destructor function inside CA class, CB class, and CC
class. Look at Destructor example below.
CA:estructor()
{
if (m_pMem != NULL)
delete [] m_pMem;
}
CB:estructor()
{
if (m_pMem != NULL)
delete [] m_pMem;
}
CC:estructor()
{
if (m_pMem != NULL)
delete [] m_pMem;
}
CC:estructor() will be executed first to detect m_pMem before it can
deallocate safely however CB:estructor() and CA:estructor() will fail,
because they think that m_pMem is NOT ALREADY deallocated before they
attempt to deallocate second time. It would be safe to put m_pMem = NULL in
both CA:estructor() and CB:estructor(), otherwise Terminate() can be
used in CMain class only.
Please provide a safe method to deallocate shared memory from three
classes. I have included my simple source code below. Please mention what
you think about my class design which is neat and better design. Please
advise.
Please note: Multiple Inheritance only allow protected functions rather
than public functions that I have chosen. Only void main(void) function is
allowed to access CMain::Run(), but it is not allowed to access all
functions inside four classes. CMain::Run() is the one that it has
authority to access ALL PROTECTED functions in three classes. Does it make
sense?
#include <stdio.h>
class CA
{
protected:
CA()
{
printf("CA Constructor\n");
}
~CA()
{
printf("CA Deconstructor\n");
}
void Run(void)
{
printf("CA Run\n");
}
unsigned char* Get_Mem(void)
{
return m_pMem;
}
void Set_Mem(unsigned char* pMem)
{
m_pMem = pMem;
}
private:
CA(const CA& rA);
CA& operator=(const CA& rA);
unsigned char* m_pMem;
};
class CB
{
protected:
CB()
{
printf("CB Constructor\n");
}
~CB()
{
printf("CB Deconstructor\n");
}
void Run(void)
{
printf("CB Run\n");
}
unsigned char* Get_Mem(void)
{
return m_pMem;
}
void Set_Mem(unsigned char* pMem)
{
m_pMem = pMem;
}
private:
CB(const CB& rB);
CB& operator=(const CB& rB);
unsigned char* m_pMem;
};
class CC
{
protected:
CC()
{
printf("CC Constructor\n");
m_pMem = new unsigned char[0x10000];
}
~CC()
{
printf("CC Deconstructor\n");
delete [] m_pMem;
}
void Run(void)
{
printf("CC Run\n");
}
unsigned char* Get_Mem(void)
{
return m_pMem;
}
void Set_Mem(unsigned char* pMem)
{
m_pMem = pMem;
}
private:
CC(const CC& rC);
CC& operator=(const CC& rC);
unsigned char* m_pMem;
};
class CMain : public CA, public CB, public CC
{
public:
CMain()
{
printf("CMain Constructor\n");
Initialize();
}
~CMain()
{
printf("CMain Deconstructor\n");
Terminate();
}
void Run(void)
{
printf("CMain Run\n");
CA::Run();
CB::Run();
CC::Run();
}
private:
void Initialize(void)
{
CA::Set_Mem(CC::Get_Mem());
CB::Set_Mem(CC::Get_Mem());
}
void Terminate(void)
{
CA::Set_Mem(NULL);
CB::Set_Mem(NULL);
}
CMain(const CMain& rMain);
CMain& operator=(const CMain& rMain);
};
void main(void)
{
CMain Main;
Main.Run();
}