[Newbie] Simple memory class

Discussion in 'C++' started by Barzo, Jun 25, 2009.

  1. Barzo

    Barzo Guest

    Hi,

    I tring to define an interface to a simple memory object and I thought
    to the following one:

    template <class T>
    class CMemory
    {
    public:
    //Properties
    bool IsEmpty();
    bool Initialized();
    long ItemsWritten();
    long Size();

    //Methods

    /** Allocate space to contain items of type T */
    long Allocate(long num_of_items);

    long Read(T* pData, long items);

    template <class Iterator>
    long Read(Iterator first, Iterator last);

    long Write(T* pData, long items);

    template <class Iterator>
    long Write(Iterator first, Iterator last);

    long Release();

    private:
    vector<T> _buffer;
    };

    First of all, this could be works?
    Is there another way to define read/write through iterators?

    Thanks in advance.
    Daniele.
     
    Barzo, Jun 25, 2009
    #1
    1. Advertising

  2. Barzo <> writes:

    > Hi,
    >
    > I tring to define an interface to a simple memory object and I thought
    > to the following one:
    >
    > template <class T>
    > class CMemory
    > {
    > public:
    > //Properties
    > bool IsEmpty();
    > bool Initialized();
    > long ItemsWritten();
    > long Size();
    >
    > //Methods
    >
    > /** Allocate space to contain items of type T */
    > long Allocate(long num_of_items);
    >
    > long Read(T* pData, long items);
    >
    > template <class Iterator>
    > long Read(Iterator first, Iterator last);
    >
    > long Write(T* pData, long items);
    >
    > template <class Iterator>
    > long Write(Iterator first, Iterator last);
    >
    > long Release();
    >
    > private:
    > vector<T> _buffer;
    > };
    >
    > First of all, this could be works?
    > Is there another way to define read/write through iterators?



    0- I prefer the following case conventions:

    - global variables, type and class name in CamelCase (with an
    initial capital, without a specific prefix).

    - local variables, parameters, method names in camelCase (with an
    initial lowcase).

    - I rather not use underlines in my identifers.



    1- Names starting with one or two underlines are reserved to the
    system. Do not name it _buffer.

    It is unfortunate that you cannot give the same name to a
    method and to a field, but since I don't like prefixing the
    field name by a letter (mBuffer), and I don't like readers to
    be prefixed by get (getBuffer()), nowdays I tend to name fields
    suffixed by an underline (which is ok for user identifiers).

    vector<T>& buffer();
    void setBuffer(const vector<T>& newData);
    vector<T>& buffer_;


    2- Could this code work?

    How could we know? There's no specification. We only know that
    we have a "memory" object. What does that mean?



    3- Is there another way to define read/write through iterators?

    Why would we define iterators to a memory chip? RAM or ROM work
    usually by direct access:

    Byte readByte(Address address);
    void writeByte(Address address,Byte byte);


    Perhaps if you could give us a specification where defining
    iterators would be meaningful it would be worthwhile to answer
    this question more precisely.

    In the meantime, it's always possible to define whatever you may
    imagine, in software systems. Your imagination is the only limit
    (within time and space).

    --
    __Pascal Bourguignon__
     
    Pascal J. Bourguignon, Jun 25, 2009
    #2
    1. Advertising

  3. Barzo

    Barzo Guest

    Re: Simple memory class

    On 25 Giu, 12:17, (Pascal J. Bourguignon)
    wrote:


    > 1- Names starting with one or two underlines are reserved to the
    > system. Do not name it _buffer.


    Thanks for the suggestions!
     

    >
    > 2- Could this code work?
    >
    >      How could we know?  There's no specification.  We only know that
    >      we have a "memory" object.  What does that mean?


    I'm sorry I leave behind some info...
    With "Could this code work?" I mean sintactically (I'm quite new to
    templates).

    I'm writing an audio library and I have to define a memory class that
    simply read/write data.

    So I thought:
    - If a class user has a pointer to some memory (eg. short* pData) and
    wants to use the class I need to create read/write methods simply
    like:

    long Read(T* pData, long items_to_read);

    - If a class user has a container or whatever? What kind of methods I
    have to create?


    Daniele.
     
    Barzo, Jun 25, 2009
    #3
  4. Pascal J. Bourguignon wrote:
    > It is unfortunate that you cannot give the same name to a
    > method and to a field, but since I don't like prefixing the
    > field name by a letter (mBuffer)


    I had the same prejudice for years, but after giving it a try in
    actual code, I actually got infatuated with the custom. I truely find
    that it helps readability when I can see from the variable name whether
    it's a local variable, a member variable or a variable local to the
    compilation unit.

    For example, consider a function like this (the code itself is not
    important itself, but the naming of the variables is):

    void MyClass::foo(int parameter)
    {
    for(int i = 0; i < parameter; ++i)
    {
    if(valueArray == someValue)
    doSomethingWith(valueArray);
    }
    }

    So where is "valueArray" and "someValue" defined? It's impossible to
    know. They could be members of MyClass, or they could be in a nameless
    namespace in this compilation unit. In fact, if the function was much
    longer and this for-loop was somewhere at the end, the variables could
    even be local to the MyClass::foo() function, defined somewhere in the
    beginning. In order to know where they are defined you need to look
    around. (Some graphical editors help finding the definition point, but
    that's only if you have one.)

    Now contrast it with this:

    void MyClass::foo(int parameter)
    {
    for(int i = 0; i < parameter; ++i)
    {
    if(gValueArray == mSomeValue)
    doSomethingWith(gValueArray);
    }
    }

    I use a naming convention such that member variables start with an 'm'
    and variables global to the compilation unit start with a 'g'. Now it's
    immediately obvious that "gValueArray" is in a nameless namespace in
    this compilation unit, while "mSomeValue" is a member variable of MyClass.

    I can honestly say that since I got accustomed to this quite simple
    naming convention, I can read my own code much more easily (especially
    months after writing it).

    (I also use the naming convention of starting constant names with "k".
    And by "constant" I mean things which can be used in places where a
    compile-time constant is expected. A "const std::vector<int>" would
    still have an "m" or "g" (unless it's local to the function, of course),
    because it's not a compile-time constant.)
     
    Juha Nieminen, Jun 25, 2009
    #4
  5. Juha Nieminen <> writes:

    > Pascal J. Bourguignon wrote:
    >> It is unfortunate that you cannot give the same name to a
    >> method and to a field, but since I don't like prefixing the
    >> field name by a letter (mBuffer)

    >
    > I had the same prejudice for years, but after giving it a try in
    > actual code, I actually got infatuated with the custom. I truely find
    > that it helps readability when I can see from the variable name whether
    > it's a local variable, a member variable or a variable local to the
    > compilation unit.
    >
    > For example, consider a function like this (the code itself is not
    > important itself, but the naming of the variables is):
    >
    > void MyClass::foo(int parameter)
    > {
    > for(int i = 0; i < parameter; ++i)
    > {
    > if(valueArray == someValue)
    > doSomethingWith(valueArray);
    > }
    > }
    >
    > So where is "valueArray" and "someValue" defined? It's impossible to
    > know. They could be members of MyClass, or they could be in a nameless
    > namespace in this compilation unit.


    Since I distinguish GlobalVariables from localVariables and
    memberVariables, it's easy to know that SomeValue would have to be a
    global variable in some namespace, while someValue must be either a
    local variable (which is seen clearly from it's declaration a few
    lines above) or a member variable. Some use the convention of always
    prefix this-> for members (variables or functions), but I dont' find
    it necessary.


    > In fact, if the function was much
    > longer and this for-loop was somewhere at the end, the variables could
    > even be local to the MyClass::foo() function, defined somewhere in the
    > beginning.


    Or in the middle. But it doesn't matter since functions must not be
    long ;-)



    > I can honestly say that since I got accustomed to this quite simple
    > naming convention, I can read my own code much more easily (especially
    > months after writing it).


    Indeed, it's mostly a question of getting accustomed to _some_
    convention. I just gave my preferences. It's not even the convention
    I have to use everyday at work...


    --
    __Pascal Bourguignon__
     
    Pascal J. Bourguignon, Jun 25, 2009
    #5
  6. Re: Simple memory class

    Barzo <> writes:

    > On 25 Giu, 12:17, (Pascal J. Bourguignon)
    > wrote:
    >> 2- Could this code work?
    >>
    >>      How could we know?  There's no specification.  We only know that
    >>      we have a "memory" object.  What does that mean?

    >
    > I'm sorry I leave behind some info...
    > With "Could this code work?" I mean sintactically (I'm quite new to
    > templates).


    Syntactically, the best placed to answer is your compiler. If you can
    compile that file, then syntactically it can work.


    > I'm writing an audio library and I have to define a memory class that
    > simply read/write data.


    And how would anything dealing with _audio_ need a memory? Computers
    need memory. Intelligent processes (whether natural or artificial)
    need memory. Water has memory. But audio stuff needs sounds,
    samples, time, sequences, measures, notes, delays, durations, etc. Is
    there any memory chip in a violin?


    > So I thought:
    > - If a class user has a pointer to some memory (eg. short* pData) and
    > wants to use the class I need to create read/write methods simply
    > like:
    >
    > long Read(T* pData, long items_to_read);
    >
    > - If a class user has a container or whatever? What kind of methods I
    > have to create?


    The methods to attach to a class don't depend on what the class _has_.
    They must depend on what the class _is_.

    For example, if you have a class Sequence, since it represents a
    sequence of notes positionned in time, you could have methods such as:

    class Sequence{
    public:
    virtual void play(AudioOutput& out,Time& position);
    virtual void pause();
    virtual void resume(Time& position);
    virtual void resume(Duration& offset);
    virtual void stop();

    virtual std::vector<Note>& getNotes() const;
    virtual std::vector<Note>& getNotes(Time& start,Time& end) const;
    virtual void addNote(Note& note,Time& position);
    virtual void removeNote(Note& note,Time& position);

    virtual void transpose(Interval& interval);
    virtual void setVolume(Volume& volume);
    virtual Volume& getVolume();
    // ...
    };



    --
    __Pascal Bourguignon__
     
    Pascal J. Bourguignon, Jun 25, 2009
    #6
  7. Pascal J. Bourguignon wrote:
    > Since I distinguish GlobalVariables from localVariables


    You have a naming clash between global variables and type names.

    (Argh, I hate using the name "global variables", because I never use
    truely global variables, only variables global to the current
    compilation unit. However, I don't know the proper term for those...)
     
    Juha Nieminen, Jun 25, 2009
    #7
  8. Barzo

    James Kanze Guest

    Re: Simple memory class

    On Jun 25, 12:17 pm, (Pascal J. Bourguignon)
    wrote:
    > Barzo <> writes:
    > 0- I prefer the following case conventions:


    > - global variables, type and class name in CamelCase (with an
    > initial capital, without a specific prefix).


    > - local variables, parameters, method names in camelCase (with an
    > initial lowcase).


    > - I rather not use underlines in my identifers.


    That's very much a personal preference. Just define a
    convention, and stick with it. About the only objective rules
    are:

    -- Distinguish between preprocessor symbols and the others.
    This is in some ways a absolute rule; on the other hand,
    most programs shouldn't define any preprocessor symbols
    anyway, except include guards (which should be inserted by
    the editor, and should have a format which can't be mistaken
    for anything else), so it really doesn't matter. The
    "standard" convention, however, is that preprocessor symbols
    are all caps. (I don't always follow it myself. But except
    for include guards, all of my preprocessor symbols do have a
    standard prefix which is all caps, and with very few
    exceptions, all have very limited scope---I'll define a
    macro for some boilerplate text, invoke it a couple of
    times, and then immediately #undef it.)

    -- Distinguish between type names and others. C++ parses
    differently depending on whether a symbol names a type or
    something else. The most frequent convention here is to
    start a type name with a capital, anything else with a small
    letter.

    A lot of coding conventions don't respect this, so it
    probably isn't an absolute rule, although I've found it
    quite useful. Also, it doesn't address templates---whether
    a name designates a template or not also affects parsing,
    but all of the conventions I know treat the names of class
    templates like type names, and the names of function
    templates like function names.

    -- Mark the separation of individual words in a symbol. There
    are two wide spread conventions here: use an underline
    (which looks sort of like a space), or start each new word
    with a capital. E.g. "newValue" or "new_value" (but not
    "newvalue". Which convention you choose isn't too
    important, as long as you choose one, and stick to it.

    > 1- Names starting with one or two underlines are reserved to the
    > system. Do not name it _buffer.


    > It is unfortunate that you cannot give the same name to a
    > method and to a field, but since I don't like prefixing the
    > field name by a letter (mBuffer), and I don't like readers to
    > be prefixed by get (getBuffer()), nowdays I tend to name fields
    > suffixed by an underline (which is ok for user identifiers).


    > vector<T>& buffer();
    > void setBuffer(const vector<T>& newData);
    > vector<T>& buffer_;


    Leading and trailing underlines aren't very visible.

    In principle, a name like "buffer" (and unqualified noun)
    should be a type, not a variable or a function. The variable
    would be myBuffer, or someParticularBuffer, and the function
    name would contain a verb. And of course, if you follow this
    rule strictly, you don't need anything else to distinguish
    between typename and others. In practice, however, it doesn't
    always work out that well. And some functions are just
    "accessors"; conceptually, the function is simply the
    presentation at the interface level of a member data element.
    In such cases, get... and set.. do seem superfluous to me. So
    some sort of convention does seem useful: my current practice is
    to prefix member variables with "my" (e.g. myBuffer), and static
    member variables with "our" (e.g. ourBuffer); this looks like
    the original rule in which variable names should be qualified
    nouns.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jun 26, 2009
    #8
  9. Barzo

    James Kanze Guest

    Re: Simple memory class

    On Jun 25, 2:05 pm, (Pascal J. Bourguignon)
    wrote:

    > Since I distinguish GlobalVariables from localVariables and
    > memberVariables,


    Isn't the correct solution here not to use global variables,
    except for things which by there nature have to be global. And
    in that case, the name of the thing should identify it enough
    that the reader knows that it has to be global.

    In practice, I've never found any problem in knowing where to
    look for a variable. I use a naming convention for member
    variables simply in order to be able to use the "raw" name for
    accessor functions.

    Distinguishing between the name of a type and the name of a
    variable or a function seems far more important to me, since
    whether something is the name of type or not determines how you
    parse a statement.

    [...]
    > Indeed, it's mostly a question of getting accustomed to _some_
    > convention. I just gave my preferences. It's not even the
    > convention I have to use everyday at work...


    But you didn't present it like that:). (At least, I got the
    impression that you were presenting more or less absolute
    rules.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jun 26, 2009
    #9
  10. Juha Nieminen <> writes:

    > Pascal J. Bourguignon wrote:
    >> Since I distinguish GlobalVariables from localVariables

    >
    > You have a naming clash between global variables and type names.
    >
    > (Argh, I hate using the name "global variables", because I never use
    > truely global variables, only variables global to the current
    > compilation unit. However, I don't know the proper term for those...)


    Indeed, there are so few global variables in a OO program, that the
    probability of a clash is close to 0.

    --
    __Pascal Bourguignon__
     
    Pascal J. Bourguignon, Jun 26, 2009
    #10
  11. Re: Simple memory class

    James Kanze <> writes:

    > On Jun 25, 12:17 pm, (Pascal J. Bourguignon)
    > wrote:
    >> Barzo <> writes:
    >> 0- I prefer the following case conventions:

    >
    >> - global variables, type and class name in CamelCase (with an
    >> initial capital, without a specific prefix).

    >
    >> - local variables, parameters, method names in camelCase (with an
    >> initial lowcase).

    >
    >> - I rather not use underlines in my identifers.

    >
    > That's very much a personal preference. Just define a
    > convention, and stick with it. About the only objective rules
    > are:
    >
    > -- Distinguish between preprocessor symbols and the others.
    > This is in some ways a absolute rule; on the other hand,
    > most programs shouldn't define any preprocessor symbols
    > anyway, except include guards (which should be inserted by
    > the editor, and should have a format which can't be mistaken
    > for anything else), so it really doesn't matter. The
    > "standard" convention, however, is that preprocessor symbols
    > are all caps. (I don't always follow it myself. But except
    > for include guards, all of my preprocessor symbols do have a
    > standard prefix which is all caps, and with very few
    > exceptions, all have very limited scope---I'll define a
    > macro for some boilerplate text, invoke it a couple of
    > times, and then immediately #undef it.)


    Indeed. Moreover, I noticed recently that you can avoid problems in
    macro expansions if you put in all upcase also the macro
    parameters. Write:

    #define MY_MACRO(ARG1,ARG2) ... ARG1 ... ARG2 ...

    instead of:

    #define MY_MACRO(arg1,arg2) ... arg1 ... arg2 ...

    >
    >> 1- Names starting with one or two underlines are reserved to the
    >> system. Do not name it _buffer.

    >
    >> It is unfortunate that you cannot give the same name to a
    >> method and to a field, but since I don't like prefixing the
    >> field name by a letter (mBuffer), and I don't like readers to
    >> be prefixed by get (getBuffer()), nowdays I tend to name fields
    >> suffixed by an underline (which is ok for user identifiers).

    >
    >> vector<T>& buffer();
    >> void setBuffer(const vector<T>& newData);
    >> vector<T>& buffer_;

    >
    > Leading and trailing underlines aren't very visible.


    In the case of member variables, I think that this is not important,
    since I will normally use the accessor everywhere (they'll be declared
    virtual too, to let subclasses modify the implementation of buffer_).


    > In principle, a name like "buffer" (and unqualified noun)
    > should be a type, not a variable or a function. The variable
    > would be myBuffer, or someParticularBuffer, and the function
    > name would contain a verb. And of course, if you follow this
    > rule strictly, you don't need anything else to distinguish
    > between typename and others. In practice, however, it doesn't
    > always work out that well. And some functions are just
    > "accessors"; conceptually, the function is simply the
    > presentation at the interface level of a member data element.
    > In such cases, get... and set.. do seem superfluous to me. So
    > some sort of convention does seem useful: my current practice is
    > to prefix member variables with "my" (e.g. myBuffer), and static
    > member variables with "our" (e.g. ourBuffer); this looks like
    > the original rule in which variable names should be qualified
    > nouns.


    That's cute.

    --
    __Pascal Bourguignon__
     
    Pascal J. Bourguignon, Jun 26, 2009
    #11
  12. Re: Simple memory class

    James Kanze <> writes:

    > On Jun 25, 2:05 pm, (Pascal J. Bourguignon)
    > wrote:
    >
    >> Since I distinguish GlobalVariables from localVariables and
    >> memberVariables,

    >
    > Isn't the correct solution here not to use global variables,
    > except for things which by there nature have to be global. And
    > in that case, the name of the thing should identify it enough
    > that the reader knows that it has to be global.
    >
    > In practice, I've never found any problem in knowing where to
    > look for a variable. I use a naming convention for member
    > variables simply in order to be able to use the "raw" name for
    > accessor functions.
    >
    > Distinguishing between the name of a type and the name of a
    > variable or a function seems far more important to me, since
    > whether something is the name of type or not determines how you
    > parse a statement.
    >
    > [...]
    >> Indeed, it's mostly a question of getting accustomed to _some_
    >> convention. I just gave my preferences. It's not even the
    >> convention I have to use everyday at work...

    >
    > But you didn't present it like that:). (At least, I got the
    > impression that you were presenting more or less absolute
    > rules.)


    Yes I did:

    >> 0- I prefer the following case conventions:

    ^ ^^^^^^


    --
    __Pascal Bourguignon__
     
    Pascal J. Bourguignon, Jun 26, 2009
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. E11
    Replies:
    1
    Views:
    4,800
    Thomas Weidenfeller
    Oct 12, 2005
  2. christopher diggins
    Replies:
    16
    Views:
    761
    Pete Becker
    May 4, 2005
  3. Joseph Turian
    Replies:
    5
    Views:
    603
  4. Fred
    Replies:
    2
    Views:
    293
  5. Christian Maier
    Replies:
    3
    Views:
    501
    John Harrison
    Feb 15, 2007
Loading...

Share This Page