Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const and pointers

Tags:

c++

constants

Edit1: I realize this is hard to understand this question without having an insight of what I'm trying to do. The class A is not complete but it essentially stand for a C-array "proxy" (or "viewer" or "sampler"). One interesting usage is too present a C-array as a 2d grid (the relevant function are not shown here). The property of this class are the following:

  • it should not own the data - no deep copyy
  • it should be copyable/assignable
  • it should be lightweight (
  • it should preserve constness (I'm having trouble with this one)

Please do not question the purpose or the design: they are the hypothesis of the question.

First some code:

class A
{
private:
    float* m_pt;
public:
    A(float* pt)
        :m_pt(pt)
    {}
    const float* get() const
    {
        return m_pt;
    }
    void set(float pt)
    {
        *m_pt = pt;
    }
};

void gfi()
{
    float value = 1.0f;
    const A ac(&value);
    std::cout<<(*ac.get())<<std::endl;
    A a = ac;
    a.set(2.0f);
    std::cout<<(*ac.get())<<std::endl;
}

Calling "gfi" generate the following output:

1
2

Assigning a with ac is a cheap way to shortcut the constness of ac. Is there a better way to protect the value which m_pt point at?

Note that I DO want my class to be copyable/assignable, I just don't want it to loose its constness in the process.

Edit0: I also DO want to have a pointer in there, and no deep copy please (let say the pointer can be a gigantic array).

Edit2: thanks to the answers, I came to the conclusion that a "const constructor" would be a useful thing to have (at least in this context). I looked it up and of course I'm not the same one who reached this conclusion. Here's an interesting discussion: http://www.rhinocerus.net/forum/language-c-moderated/569757-const-constructor.html

Edit3: Finally got something which I'm happy with. Thanks for your help. Further feedback is more than welcome

template<typename T>
class proxy
{
public:
    typedef T elem_t;
    typedef typename boost::remove_const<T>::type elem_unconst_t;
    typedef typename boost::add_const<T>::type elem_const_t;
public:
    elem_t* m_data;
public:
    proxy(elem_t* data = 0)
        :m_data(data)
    {}
    operator proxy<elem_const_t>()
    {
        return proxy<elem_const_t>(m_data);
    }
}; // end of class proxy

void test()
{
    int i = 3;
    proxy<int> a(&i);
    proxy<int> b(&i);
    proxy<const int> ac(&i);
    proxy<const int> bc(&i);
    proxy<const int> cc = a;
    a=b;
    ac=bc;
    ac=a;
    //a=ac; // error C2679: binary '=' : no operator found which takes a right-hand operand of type...
    //ac.m_data[0]=2; // error C3892: 'ac' : you cannot assign to a variable that is const
    a.m_data[0]=2;
}

2 Answers

Your class is badly designed:

  • it should use float values, not pointers
  • if you want to use pointers, you probably need to allocate them dynamically
  • and then you need to give your class a copy constructor and assignment operator (and a destructor) , which will solve the problem

Alternatively, you should prevent copying and assignment by making the copy constructor and assignment op private and then not implementing them.

You can trick around with proxy pattern and additional run-time constness boolean member. But first, please tell us why.

like image 37
Pavel Radzivilovsky Avatar answered Mar 10 '26 16:03

Pavel Radzivilovsky



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!