c++visual-studio-2008namespacesfriendvisual-studio-2008-sp1

friend class across namespaces & different .H files


I'm trying to make the following compile under VS 2008 SP1 C++ project, but the friend class statement doesn't seem to have any effect. (See error message in the last code snippet.)

What am I doing wrong with the friend definition?

// EncryptionTypes.h file
#pragma once

//#include "Encryption.h"   //adding this line doesn't help


using namespace crypto;

struct FILE_DATA_CACHE{
    FILE_DATA_CACHE()
    {
    };

    ~FILE_DATA_CACHE()
    {
    }

    friend class CEncryption;

private:
    bool _isIndexFileUsed()
    {
        return bResult;
    }
};

then:

// Encryption.h
#pragma once

#include "EncryptionTypes.h"


namespace crypto
{

class CEncryption
{
public:
    CEncryption(void);
    ~CEncryption(void);
private:
    BOOL _openFile();

private:
    FILE_DATA_CACHE gFData;
};

};

and lastly:

// Encryption.cpp
#include "StdAfx.h"
#include "Encryption.h"


namespace crypto
{

CEncryption::CEncryption(void)
{
}

CEncryption::~CEncryption(void)
{
}

void CEncryption::_openFile()
{
    //The line below generates this error:
    //1>.\Encryption.cpp(176) : error C2248: 'FILE_DATA_CACHE::_isIndexFileUsed' : cannot access private member declared in class 'FILE_DATA_CACHE'
    //1>        c:\users\blah-blah\EncryptionTypes.h(621) : see declaration of 'FILE_DATA_CACHE::_isIndexFileUsed'
    //1>        c:\users\blah-blah\EncryptionTypes.h(544) : see declaration of 'FILE_DATA_CACHE'

    gFData._isIndexFileUsed();
}

};

Solution

  • You have a circular dependency problem.

    Encryption.h needs FILE_DATA_CACHE, which is defined in EncryptionTypes.h.
    EncryptionType.h needs CEncryption, which is defined in Encryption.h.

    Fortunately, you can get by with using a forward declaration of CEncryption in EncryptionType.h.

    Modify EncryptionType.h to:

    // EncryptionTypes.h file
    #pragma once
    
    // Can't #include Encryption.h. That will lead to circular
    // #includes.
    namespace crypto
    {
       // Forward declaration of crypto::CEncryption
       class CEncryption;
    }
    
    struct FILE_DATA_CACHE{
       FILE_DATA_CACHE()
       {
       };
    
       ~FILE_DATA_CACHE()
       {
       }
    
       friend class crypto::CEncryption;
    
       private:
       bool _isIndexFileUsed()
       {
          return bResult;
       }
    };