static stuff

Discussion in 'C++' started by Jon Slaughter, Jun 30, 2005.

  1. Is there any way to declare a member of a base class to make the itself in
    the derived class to be static?

    i.e., I have two classes

    class Base
    {

    protected:
    char *name;

    };

    class Derived1 : Base
    {
    public:
    Get_Name(char *s)
    {
    strcpy(s,name); // or whatever
    }

    };

    class Derived2 : Base
    {
    public:
    Get_Name(char *s)
    {
    strcpy(s,name); // or whatever
    }

    };

    the problem is that each derived object allocates a name pointer and for my
    application each object of the derived class will all have the same name(the
    name represents the name of the class)


    but if I did this

    class C
    {
    private:
    static char name[] = "C Class";
    public
    Get_Name(char *s)
    {
    strcpy(s, C::name);
    }
    }

    class Q
    {
    private:
    static char name[] = "Q Class";
    public
    Get_Name(char *s)
    {
    strcpy(s, Q::name);
    }
    }

    then there is only one name pointer for all the objects of the C class...
    but he problem is that I will have many different types of classes that all
    inherent from a base class and I want to be able to differentiate them by
    there name... but I don't want to have to declare a static variable in each
    of the different class declerations(cause lets say I forget one).

    I'm pretty sure that if I do this:

    class Base
    {

    protected:
    static char *name;

    };

    class Derived1 : Base
    {
    public:
    Derived1()
    {
    strcpy("Derived1 class", Base::name); // or is it Derived1::name?
    }
    Get_Name(char *s)
    {
    strcpy(s,name); // or whatever
    }

    };


    class Derived2 : Base
    {
    public:
    Derived2()
    {
    strcpy("Derived2 class", Base::name); // or is it Derived2::name?
    }
    Get_Name(char *s)
    {
    strcpy(s,name); // or whatever
    }

    };

    that both the derived classes will be stepping over each others shoes.

    Basicaly I want to have some static members of derived classes but force
    them to be declared and to be static in an elegant way(and not by declaring
    the member static in all those classes I will have to create)


    Also I am wondering that if I declare an array as const does that gaurantee
    that it cannot be changed? (i.e. does the compiler stick it in some type of
    read only memory or something?)

    Thanks,
    Jon
     
    Jon Slaughter, Jun 30, 2005
    #1
    1. Advertisements

  2. On Thu, 30 Jun 2005 08:45:26 +0400, Jon Slaughter

    []
    Just think of inheritance in another way. Make your derived classes base
    classes that are used for generation of "concrete" derived classes.
    Somethink like this:

    #include <string>
    #include <iostream>

    template<class B, char const* Name>
    struct decorator : B
    {
    // forwarding ctors if needed
    decorator() {}
    template<class T1> decorator(T1 const& t1) : B(t1) {}
    template<class T1, class T2> decorator(T1 const& t1, T2 const& t2) :
    B(t1, t2) {}
    // ...

    std::string name() const { return Name; }
    };

    struct A_impl {};
    struct B_impl {};

    extern char const A_name[] = "A class";
    extern char const B_name[] = "B class";

    typedef decorator<A_impl, A_name> A;
    typedef decorator<B_impl, B_name> B;

    int main()
    {
    A a;
    std::cout << a.name() << std::endl;
    B b;
    std::cout << b.name() << std::endl;
    }
     
    Maxim Yegorushkin, Jun 30, 2005
    #2
    1. Advertisements

  3. but this looks like it will store Name for each object created?

    I will have many objects with the same class name

    like I will have

    typedef decorator<A_impl, A_name> A1;
    typedef decorator<A_impl, A_name> A2;
    typedef decorator<A_impl, A_name> A3;
    typedef decorator<A_impl, A_name> A4;

    so will the template store A_name 4 times(or atleast a pointer in each
    object?) or will all references to A_name refer to only one location? (heh,
    I will have to study up on templates to see what is exactly going on here...
    I'm only familiar with the very basics of them(since I haven't programmed in
    a very very long time)

    Thanks

    Jon
     
    Jon Slaughter, Jun 30, 2005
    #3
  4. On Thu, 30 Jun 2005 09:22:26 +0400, Jon Slaughter

    []
    No, Name is a pointer and it is not stored as a data member in objects,
    rather it's hardcoded in code where you refer to it.
    Here you did not declare any objects, rather you declared A1..4 to be
    As I said the pointer is hardcoded. The string literal used to initialized
    the pointer has external linkage and static storage duration, which means
    there will be only one instance of the literal in your program.
     
    Maxim Yegorushkin, Jun 30, 2005
    #4
  5. heh yeah... I see now(not sure what I said that)(I think I understand the
    code now for the most part... maybe it was just to late last night).
    ok, I think I see why. when you do "return name" in the template it is and
    the template is used to create the class it just returns the address of that
    string which was declared only once and has only one "instance".

    Now I have a new question. I figured that, say, if I create a bunch of char
    pointers and then all initalize them to the same string..

    maybe something like

    strcpy(p1, "Note")

    then somewhere else

    strcpy(p2, "Note")

    etc...

    is the compiler going to make one instance of Note? i.e. does it compact all
    string literals in the program into a table and remove identical strings?

    Thanks

    Jon
     
    Jon Slaughter, Jun 30, 2005
    #5
  6. On Thu, 30 Jun 2005 18:11:52 +0400, Jon Slaughter

    []
    The you'd probably get a SIGSEGV trying to strcpy to an uninitialized
    pointer.

    char const* p1 = "note";
    char const* p2 = "note";

    This is done in the linker. Modern GNU and M$ linkers do that.
     
    Maxim Yegorushkin, Jun 30, 2005
    #6
  7. heh, yeah, but was just some C++ pseudo code ;)
    Ok... so at most I would just be wasting a pointer for storage of those
    address... though I think its better to use the literal address(instead of a
    pointer to the literal address) like you have done.

    Thanks again.
    Jon
     
    Jon Slaughter, Jun 30, 2005
    #7
  8. ok, I am wondering why you went through all the trouble of declaring the
    template to have a base class?

    I came up with this example:

    template<char const *Name>
    class test
    {
    public:
    char const *Get_Name()
    {
    return Name;
    }
    }

    // must be extern for some reason
    extern char const Name[] = "Name";


    int main()
    {
    test<Name> t;

    // This line is invalid... not sure exactly why.. I suppose the compiler
    doesn't internally treat "Name" as a char const variable or something and so
    it doesn't really have an address(i..e its not treated as a pointer but a
    literal I suppose)
    test<"Name"> t;

    cout << t.Get_Name();
    }


    now, can't I use that template in the creation of my new class(which would
    have been my derived class before)? I mean
    can't I do something like

    class new_test : test<Name>
    {

    blah...
    }

    ? I mean maybe not valid C++ code but surely I don' thave to really derive a
    new class... I just copy the stuff in the template to the new class... so it
    would look something like:

    class new_test : test<Name>
    {
    public:
    char const *Get_Name()
    {
    return Name;
    }

    blah...
    }


    I mean surely C++ has a way to extend a class from another template without
    deriving it from an object created by the template? (i.e. I don't think I
    will really need a base class if I use a template like that because the
    template can be included directly in the class and act part of that class?)?

    Thanks again.

    Jon
     
    Jon Slaughter, Jun 30, 2005
    #8
  9. On Fri, 01 Jul 2005 00:37:47 +0400, Jon Slaughter

    []
    You can have the template as a base class as well.
    Yes, you can do it as well.
     
    Maxim Yegorushkin, Jul 2, 2005
    #9
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.