Thread: Generic Template Pointer

  1. #1
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856

    Generic Template Pointer

    Okay, now I've got a real brain blender...

    I've got a base class: A
    There are two derived classes: B, C

    B is a template for any derived type of C.
    C is an ADT that needs a data member that is a pointer to a B. Therein lies my trouble. Such a thing is circular, so how can it be done?

    Let me illustrate:
    Code:
    class A {
    };
    
    template <typename T>
    class B : public A {
    };
    
    class C : public A {
      B<C> *pointerToB;// B<C2>* would work, but C2 is user-defined
      void foo() = 0;// for clarity
    };
    
    //
    // user's code follows
    //
    class C2 : public C {
      void foo() { }
    };
    
    class B2 : public B<C2> {
    };
    I cannot create the variable pointerToB because I need to specify the template parameter for B, but I cannot do that because that class is defined by the user (derived from C).

    This is either a strange problem that has an easy fix one of you knows about or it's a very poorly designed set of classes.

    I guess if all else fails I can just make the pure virtual functions stop being pure virtual, but hopefully there is another solution.
    Last edited by LuckY; 10-19-2004 at 04:21 PM.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    You can make C a template class of the type needed for B<>*pointerToB.

    >> or it's a very poorly designed set of classes.
    Tell us what A, B, C, C2, and B2 are actually, and we'll let ya know (of better ways to do it atleast, if any)

  3. #3
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    Your suggestion is exactly what I had pictured in my head (what I posted below) and doesn't appear to be something the compiler will like since for C2 it would need to instantiate C<B2> but for that it would first have to instantiate B2 which would require the instantiation of B<C2> which would require C2 (and on and on)...
    Code:
    template <typename T>
    class C {
      B<C<T>> *pointerToB;
    };
    
    //
    // user-defined code
    //
    class B2;
    
    class C2 : public C<B2> {
    };
    
    class B2 : public B<C2> {
    };
    I think I will just go ahead and remove the pure virtual guy (there's only one of them and it's called when data is queued for a socket and ready to be recv()'d).

    ME: >> or it's a very poorly designed set of classes.
    YOU: >> Tell us what A, B, C, C2, and B2 are, and we'll let ya know

    ME: That's what I'm afraid of... ;P

    [edit]
    btw, I will detail what the heck this stuff is tomorrow (when I have more time), so be sure to comment.
    [/edit]
    Last edited by LuckY; 10-19-2004 at 10:20 PM.

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> B<C<T>> *pointerToB;
    Gotta put a space between >>, otherwise it's right shift.

    gg

  5. #5
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    Okay, here's what I've been doing...

    Class A = class Socket // note these names are just for illustration
    Class B = class Server : public Socket
    Class C = class Client : public Socket

    The way Server works is it uses a function that causes the socket to begin listening and then starts a thread that just endlessly loops checking for readability and accepting clients as they connect. Once a client is accepted a new Client object is created (dynamically) and it is added into the Server's vector of pointers to Client objects.

    The Client does this: once a connection is established (either by connecting as a client or by being accepted by a server) a thread starts running that just endlessly loops checking if the socket is readable and if it is, it checks if the connection was closed/lost and if not, it calls a function named OnReceive() then continues with the looping.

    The first issue is that if a Client object is running at the server end and it loses the connection (due to error or closure by the actual client) [this is detected in OnReceive()] it needs to inform the server that owns it that it is closing so it can be removed from the vector. This is why the Client class needs a pointer to the templated Server.

    Another issue is that Client needs to be derived so OnReceive() can be overridden to perform whatever recv()'ing it needs. That said, the Server's vector of Client objects will not call the derived Client's OnReceive(). It will call the base version. This is why I made the Server class a template (so the user can instantiate a Server that can call their version of OnReceive()).

    In doing all this I ran into several problems (which I won't list here), but have all been resolved as of 45 seconds ago. It is now running very smoothly and is very stable from what I can tell.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Function template has already been defined
    By Elysia in forum C++ Programming
    Replies: 19
    Last Post: 04-14-2009, 10:17 AM
  2. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  3. Ban pointers or references on classes?
    By Elysia in forum C++ Programming
    Replies: 89
    Last Post: 10-30-2007, 03:20 AM
  4. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  5. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM