CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10

Thread: Circular include problem

  1. #1
    Join Date
    Jan 2009
    Posts
    388

    Circular include problem

    I have entered into a circular include problem. I have a class:

    Code:
    #include "TestConnection.h"
    #include "oci.h"
    #include "SU_ORADB_imp.h"
    
    class DBTestConnection final : public Connection
    {
    private:
    	SU_ORADB_imp* imp_{ nullptr };
    	bool m_connected = false;
    	// methods
    	DBTestConnection();
    	// friend class
    	friend ConnectionPoolFactory<DBTestConnection>;
    
    public:
    	bool heart_beat() override { return m_connected; }
    	bool is_healthy() override { return m_connected; }
    	void disconnect() override;
    	bool connect() override;
    	void do_something();
    	~DBTestConnection() override;
    	OCISvcCtx* GetServerContext() { return imp_->_svchp; }
    };
    and another class:
    Code:
    #pragma once
    
    #include "oci.h"
    #include "ConnectionFactory.h"
    
    class SU_ORADB_imp
    {
    private:
    	OCISvcCtx* _svchp;	// just for testing purpose
    	// methods
    	void Init();
    
    protected:
    	PoolProxy GetConnection();
    	static std::unique_ptr<ConnectionPool> pool_;
    
    public:
    	void Connect();
    	void Disconnect();
    	SU_ORADB_imp();
    	~SU_ORADB_imp();
    	void DoSqlSelect();
    
    	friend class DBTestConnection;
    };
    but I got these errors:
    Code:
    dbtestconnection.h(10): error C2143: syntax error: missing ';' before '*'
    dbtestconnection.h(10): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    dbtestconnection.h(10): error C2334: unexpected token(s) preceding '{'; skipping apparent function body
    dbtestconnection.h(24): error C2065: 'imp_': undeclared identifier
    and

    Code:
    connectionfactory.h(11): error C2065: 'DBTestConnection': undeclared identifier
    connectionfactory.h(12): error C2923: 'ConnectionPoolFactory': 'DBTestConnection' is not a valid template type argument for parameter 'T'
    connectionfactory.h(27): error C2913: explicit specialization; 'ConnectionPoolFactory' is not a specialization of a class template
    How can I get rid of this issue ? Can you help me a little bit ? I put here a test project to illustrate my problem.
    Attached Files Attached Files

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,484

    Re: Circular include problem

    Is this a circular class reference problem - both classes referring to each other?

    If yes, then you need to forward declare one class before it is used in the other. Note that if this is the problem and you do this, you can only access the members of the forward declared class in the other via pointers - other you get an error message re incomplete class.

    Code:
    struct Fclass;
    
    struct Myclass {
    	Fclass* fclas {};
    
    	Myclass() {}
    	Myclass(Fclass* fc) : fclas(fc) {}
    };
    
    struct Fclass {
    	Myclass mclas;
    };
    
    int main()
    {
    	Fclass fc;
    	Myclass mc(&fc);
    }
    If this isn't the problem, can you provide a simple one file compilable example.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++20 Compiler: Microsoft VS2019 (16.10.0)

  3. #3
    Join Date
    Jan 2009
    Posts
    388

    Re: Circular include problem

    I have the class DBTestConnection:

    Code:
    #include "SU_ORADB_imp.h"
    
    class DBTestConnection final : public Connection
    {
    private:
    	SU_ORADB_imp* imp_{ nullptr };
    ...
    error:
    Code:
    dbtestconnection.h(10): error C2143: syntax error: missing ';' before '*'
    of course, I tried to declare only this class:
    Code:
    class SU_ORADB_imp;
    
    class DBTestConnection final : public Connection
    {
    private:
    	SU_ORADB_imp* imp_{ nullptr };
    ...
    the I got
    Code:
    dbtestconnection.h(27): error C2027: use of undefined type 'SU_ORADB_imp'
    I mean, when I am trying to use this memeber (imp_). Seems it is an endless loop around the tale.
    Last edited by mesajflaviu; May 11th, 2021 at 12:07 PM.

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,484

    Re: Circular include problem

    How and where are you using imp_ ? Can you provide a minimal test compilable program that shows the problem.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++20 Compiler: Microsoft VS2019 (16.10.0)

  5. #5
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,154

    Re: Circular include problem

    A quick attempt to fix your problem did not lead to success.
    I would try the following:
    - disable the precompiled header
    - in each file that is reported to have errors: comment out all includes, and try to get it to compile with forward declarations
    - move all implementation from .h to .cpp files
    - move the definition of the factory to a single header file

  6. #6
    Join Date
    Jan 2009
    Posts
    388

    Re: Circular include problem

    I have simplified the sample project, and after few changes, I left just one point error:

    Code:
    connectionfactory.h(8): error C2065: 'DBTestConnection': undeclared identifier
    connectionfactory.h(9): error C2923: 'ConnectionPoolFactory': 'DBTestConnection' is not a valid template type argument for parameter 'T'
    connectionfactory.h(23): error C2913: explicit specialization; 'ConnectionPoolFactory' is not a specialization of a class template
    and that error fire here:

    Code:
    #pragma once
    
    #include "connection.h"
    #include "pool.h"
    #include "DBTestConnection.h"
    
    template <>
    class ConnectionPoolFactory<DBTestConnection>  // <--- error
    {
    public:
    	static std::unique_ptr<ConnectionPool> create(const std::uint16_t& num_connections)
    	{
    		std::vector<std::unique_ptr<Connection>> connections;
    		for (std::uint16_t k = 0; k < num_connections; ++k)
    		{
    			connections.emplace_back(std::unique_ptr<DBTestConnection>(new DBTestConnection{}));
    		}
    		return std::unique_ptr<ConnectionPool>(new ConnectionPool{ std::move(connections) });
    	}
    
    private:
    	ConnectionPoolFactory() = default;
    };
    Attached Files Attached Files

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,484

    Re: Circular include problem

    Provide a minimal test compilable program that shows the problem - one .cpp file of at most a couple of dozen lines (no .h files etc) that can be pasted here and copy/pasted easily into the compiler. Providing a zip file consisting of multiple .h/.cpp files within a project isn't really going to help.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++20 Compiler: Microsoft VS2019 (16.10.0)

  8. #8
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    19,980

    Re: Circular include problem

    I agree with 2kaud.
    The posted zip projects are two complicated for investigations since there is a lot of relationships between classes, headers and sources files (plus a lot of or, I'd say, too many #includes!).
    Victor Nijegorodov

  9. #9
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,154

    Re: Circular include problem

    Try this DBTestConnection.h
    Code:
    #pragma once
    
    #include "TestConnection.h"
    #include "connection.h"
    //#include "SU_ORADB_imp.h"
    #include "oci.h"
    //#include "ConnectionFactory.h"
    
    class SU_ORADB_imp;
    
    class DBTestConnection final : public Connection
    {
    private:
    	SU_ORADB_imp* imp_{ nullptr };
    	bool m_connected = false;
    	// methods
    	DBTestConnection();
    	// friend class
    	//friend ConnectionPoolFactory<DBTestConnection>;
    	 template <typename T>
    	 friend class ConnectionPoolFactory;// <DBTestConnection>
    
    public:
    	void disconnect() override;
    	bool connect() override;
    	void do_something();
    	~DBTestConnection() override;
    	OCISvcCtx* GetServerContext();
    };
    The problem is
    a) in DBTestConnection.h you include ConnectionFactory.h, which then needs to know class DBTestConnection. But the compiler has not seen a declaration of it at that point.
    b) your friend declaration is incorrect, but the compiler didn't even come to that point.

  10. #10
    Join Date
    Jan 2009
    Posts
    388

    Re: Circular include problem

    Thank you a lot Richard !

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)