我有2个类,其中一个有map<string, vector<string> >
我希望能够在其他课程中使用它。这是我的代码:
class a
{
map<string, vector<string> > m;
public:
const map<string, vector<string> > & get()
{
return m;
}
};
class b
{
a obj;
public:
void test()
{
map<string, vector<string> > m= obj.get();
// and then print
}
};
int main(int argc, char ** argv)
{
b bobj;
bobj.test();
return 0;
}
我在class a
中返回对地图的引用是否正确?它有效,但我只想确认它是否正确完成/我很幸运/有关代码的任何其他评论。
感谢您的帮助。
答案 0 :(得分:13)
如果您不想更改b::test()
中的地图,则不应复制该地图:
const map<string, vector<string> >& m = obj.get(); // note the const &
我的反对意见:
专业:a::get()
应为const
:
const map<string, vector<string> > & get() const // note the const at the end
次要:我会使用typedef
为地图的类型创建别名。
typedef map<string, vector<string> > my_map_t;
轻微:我完全看不出b
的用途。
鉴于这些,我的代码看起来像这样:
class a
{
public:
typedef map<string, vector<string> > my_map_t;
const my_map_t & get() const {return m;}
private:
my_map_t m;
};
void test(const a& obj)
{
const a::my_map_t& m = obj.get();
// and then print
}
int main()
{
a obj;
test(obj);
return 0;
}
答案 1 :(得分:2)
是的,这是返回对常量对象的引用的正确方法。
但是,在收到返回引用的test
函数中,左侧不是引用。这意味着您实际上将在此函数中创建整个地图的副本。一个简单的更改将解决该问题,然后test
函数变为零拷贝:
void test()
{
map< string, vector<string> > const & m = obj.get();
// and then print
}
答案 2 :(得分:1)
这是正确的,但您应该使用引用来存储obj.get()
的结果,如前所述。如果你做了这样的事情,这将是不正确的:
const map< string, vector<string> >& foo()
{
map< string, vector<string> > m;
// ...
return m;
}
因为在这种情况下,m
完成执行后foo()
将不再存在。
答案 3 :(得分:0)
让我向您展示一个非常简单的示例,而不是直接回答您的问题。考虑一个简单的类A,其中有一个double作为其私有成员。
class A{
private:
double a;
public:
A(double _a);
double
get_a();
double&
get_aref();
const double&
get_aconstref();
};
该类的实现。非常简单
A::A(double _a): a(_a){
};
// Getters
double
A::get_a() {
return a;
}
double&
A::get_aref(){
return a;
}
const double&
A::get_aconstref(){
return a;
}
现在让我们进入使用A类的主程序。
int main(){
A ainst(6.0);
double a = ainst.get_a();
std::cout << "a = " << a << std::endl;
a++;
std::cout << "a+1 = " << a << std::endl;
std::cout << "Meanwhile, in class A, value of a = " << ainst.get_a() << std::endl;
double& aref = ainst.get_aref();
std::cout << "aref = " << aref << std::endl;
aref++;
std::cout << "aref+1 = " << aref << std::endl;
std::cout << "Meanwhile, in class A, value of a = " << ainst.get_a() << std::endl;
const double& aconstref = ainst.get_aconstref();
std::cout << "aconstref = " << aconstref << std::endl;
// aconstref++;
// std::cout << "aconstref+1 = " << aconstref << std::endl;
std::cout << "Meanwhile, in class A, value of a = " << ainst.get_a() << std::endl;
return 0;
}
所以你只能做一个
const double& aconstref = ainst.get_aconstref();
而不是
double& aconstref = ainst.get_aconstref();
如果类的方法以const T&amp;形式返回类型T的类成员之一,则意味着它不希望调用者更改该成员。在上面的例子中,T是双精度数。在nits位置替换std :: map并保持相同的逻辑。我希望这很有说服力。如果删除两个注释行,编译器会抱怨,因为您正在尝试更改该引用。