What is a good place to place a constant in the following C ++ expression

Consider the following class member:

std::vector<sim_mob::Lane *>  IncomingLanes_;

the above container should store a pointer to some if my objects are lane. I do not want routines to use this variable as an argument to be able to modify Lane objects. At the same time, I do not know where to put the keyword 'const', which does not prevent me from filling the container.

Could you help me with this?

Thank you and respect vahid

Edit: Based on the answers I have received so far (many thanks to all of them), suppose this sample:

#include <vector>
#include<iostream>
using namespace std;

class Lane
{
private:
    int a;
public:
    Lane(int h):a(h){}
    void setA(int a_)
    {
        a=a_;
    }
    void printLane()
    {
        std::cout << a << std::endl;
    }
};

class B
{

public:
    vector< Lane const  *> IncomingLanes;
    void addLane(Lane  *l)
    {
        IncomingLanes.push_back(l);
    }

};

int main()
{
    Lane l1(1);
    Lane l2(2);
    B b;
    b.addLane(&l1);
    b.addLane(&l2);
    b.IncomingLanes.at(1)->printLane();
    b.IncomingLanes.at(1)->setA(12);
    return 1;
}

I mean:

b.IncomingLanes.at (1) → printLane ()

should work on IncomingLanes no problem AND

b.IncomingLanes.at (1) → set A (12)

. ( !)

, . , , , , . Thaks agian

+5
7

:

std::vector<const sim_mob::Lane *>  IncomingLanes_;

:

std::vector<sim_mob::Lane const *>  IncomingLanes_;

C/C++ typename * typename const * .

:

, ,

b.IncomingLanes.at(1)->printLane()

printLane :

void printLane() const // Tell compiler that printLane doesn't change this
  {
  std::cout << a << std::endl;
  }
+2

: , shared_ptr, . .

, , , design-const, , . , const-reference. , -, const (.. this const , this ).

, const-reference . lane - , ctor (s).

:

: :

#include <vector>
#include <iostream>
//using namespace std; I'd rather type the 5 characters

// This is almost redundant under the current circumstance
#include <vector>
#include <iostream>
#include <memory>
//using namespace std; I'd rather type the 5 characters

// This is almost redundant under the current circumstance
class Lane
{
private:
    int a;
public:
    Lane(int h):a(h){}
    void setA(int a_) // do you need this?
    {
        a=a_;
    }
    void printLane() const // design-const
    {
        std::cout << a << std::endl;
    }
};

class B
{    
    // be consistent with namespace qualification
    std::vector< Lane const * > IncomingLanes; // don't expose impl. details
 public:
    void addLane(Lane const& l) // who responsible for freeing `l'?
    {
        IncomingLanes.push_back(&l); // would change
    }
    void printLane(size_t index) const
    {
#ifdef _DEBUG 
        IncomingLanes.at( index )->printLane();
#else
        IncomingLanes[ index ]->printLane();
#endif
    }        
};

int main()
{
    Lane l1(1);
    Lane l2(2);
    B b;
    b.addLane(l1);
    b.addLane(l2);
    //b.IncomingLanes.at(1)->printLane(); // this is bad
    //b.IncomingLanes.at(1)->setA(12); // this is bad
    b.printLane(1);

    return 1;
}

, .,

, , , ( ). , unique_ptr shared_ptr .

, unique_ptr , std::move. , pointer to const Lane ( ).

+3

, , (.. , const). , nonmember std::vector (.. ).

, const - IncomingLanes_. IncomingLanes_ std::vector<sim_mob::Lane *>::const_iterator ( , , GetIncomingLanesBegin() GetIncomingLanesEnd()).

+1

:

std::vector<const sim_mob::Lane *>  IncomingLanes_;

, , . .

   IncomingLanes_.push_back(someLine); // Ok
   IncomingLanes_[0] = someLine; //error
   IncomingLanes_[0]->some_meber = someting; //error
   IncomingLanes_.erase(IncomingLanes_.end()); //OK
   IncomingLanes_[0]->nonConstMethod(); //error
+1

, IncomingLanes, , const , .

, , , IncomingLanes . IncomingLanes const getter.

0

, , , , , const.

 const std::vector<sim_mob::Lane*> // means the vector is const, not the pointer within it
 std::vector<const sim_mob::Lane*> // means no one can modify the data pointed at.

, , , :

 const_cast<sim_mob::Lane*>(theVector[i])->non_const_method();

, sim_mob:: Lane - const sim_mob:: Really_Lane . , "Lane" "" dynamic_cast?

0

const , .

Do vector , .

(*) :

class B {
public:
    std::vector<Lane> const& getIncomingLanes() const { return incomingLanes; }

    void addLane(Lane l) { incomlingLanes.push_back(l); }

private:
    std::vector<Lane> incomingLanes;
};

:

  • vector
  • class clients cannot modify contents vector( Laneinstances)

and, of course, the class can fully access the content vectorand modify it as it sees fit.

Your new procedure mainwill look like this:

int main()
{
    Lane l1(1);
    Lane l2(2);
    B b;
    b.addLane(l1);
    b.addLane(l2);
    b.getIncomingLanes().at(1).printLane();
    b.getIncomingLanes().at(1).setA(12); // expected-error\
        // { passing ‘const Lane’ as ‘this’ argument of
        //   ‘void Lane::setA(int)’ discards qualifiers }
    return 1;
}

(*) This is weak in the sense that, although the attribute itself is not disclosed, because we give a link to it to the outside world in practice, clients are not really protected.

0
source

All Articles