我有这个功能
int getrelation(string name, RELATION& output){
bool found=0;
int index=0;
for(int i=0;i<a_attributes.size();i++){
if(name==a_attributes[i].str_name){
found=1;
index=i;
}
}
if(!found){
printf("relation not found");
return 1;
}
output=a_attributes[index];
return 0;
}
关系是一个班级 a_attributes是关系的载体。
它应该返回对关系对象的引用。调用getrelation()
后,如果我更改输出值,那么a_attributes[index]
的值也应该更改,因为这是一个浅表副本,对吗?
答案 0 :(得分:0)
这实际上取决于你的赋值运算符,这里没有列出。
该行
output=a_attributes[index];
将使用赋值运算符来设置输出。如果该赋值运算符进行深层复制,那么就可以获得深层复制。
答案 1 :(得分:0)
如果你没有重载赋值运算符,那么不会,你将得不到浅拷贝。分配output=a_attributes[index];
时,您正在制作a_attributes[index]
的副本。因此,对返回值的任何修改都不会影响a_attributes
。
如果你想要一个浅拷贝,那么你必须要overload the assignment operator,或者通过引用传递一个指针,把参数改为RELATION& *output
,然后传入一个指针,然后改变最后一个行到output=&a_attributes[index];
。
您的代码还有另一个问题。您无法直接将字符串与==
中的if(name==a_attributes[i].str_name)
进行比较,因为只有字符串存储在同一位置时才会返回true。您需要使用类似strcmp()
的内容。
答案 2 :(得分:0)
不,因为你在这里是一份深刻的副本。 output
参数是对类RELATION
的某个对象的引用。因此,如果您在getrelation
函数中更改该对象,则用户将注意到这些更改,因为您更改了引用的对象。但是,在这一行 - output=a_attributes[index];
上,您基本上调用了对象output
的复制赋值运算符,该运算符执行a_attributes[index]
返回的对象中每个字段的深层副本到output
引用的对象。 {1}},除非复制赋值运算符过载并执行不同的操作。这基本上是因为您无法更改引用的值 - 例如,它不能引用一个对象并最终引用另一个对象。要实现你想要的东西(如果我说得对你好),你必须将指针传递给指向对象的指针(或对指针的引用),然后你可以通过取消引用它来改变指向该对象的指针。像这样:
int getrelation(string name, RELATION **output){
bool found=0;
int index=0;
for(int i=0;i<a_attributes.size();i++){
if(name==a_attributes[i].str_name){
found=1;
index=i;
}
}
if(!found){
printf("relation not found");
return 1;
}
*output= &a_attributes[index];
return 0;
}
希望它有所帮助!
答案 3 :(得分:0)
否...如果要获取对输出对象的引用,则将类型为RELATION
的引用指针传递给函数,而不是引用到对象的引用输入RELATION
。
例如:
int getrelation(string name, RELATION*& output)
{
bool found=0;
int index=0;
for(int i=0;i<a_attributes.size();i++){
if(name==a_attributes[i].str_name){
found=1;
index=i;
}
}
if(!found){
printf("relation not found");
return 1;
}
output = &(a_attributes[index]); //take the address-of object
return 0;
}
然后你会像这样调用你的函数:
RELATION* ptr_to_object = NULL;
string argument_name;
//...more code to initialize argument_name
if (getrelation(argument_name, ptr_to_object) == 1)
{
//...handle error condition
}
//now ptr_to_object points to your a_attribute[index] object
所以此时,您现在可以取消引用ptr_to_object
,并且您将获得a_attribute[index]
处的对象。然后,您可以通过取消引用指针来更改该对象的属性。唯一的警告是你不应该在delete
上调用ptr_to_object
,因为它不“拥有”被指向的对象,并且返回的指针不指向内存段的开头。已分配new
。此外,如果容器a_attribute
处置对象(即,如果它是std::map
或std::vector
),则指针将指向无效的存储位置。因此,您必须确保容器超出您用作对象引用的指针。
答案 4 :(得分:0)
这里有一些更惯用的C ++,虽然返回实际的迭代器也是一个好主意。
struct rel_by_name : public std::binary_function<const std::string&, const RELATION&, bool> {
bool operator()(const std::string& s, const RELATION& rel) {
return s == rel.str_name;
}
};
RELATION& getrelation(const std::string& name) {
std::vector<RELATION>::iterator it = std::find_if(a_attributes.begin(), a_attributes.end(),
std::bind1st(rel_by_name(), name));
if(it == a_attributes.end()) {
//not found, report error by throwing or something
}
else { return *it; }
}
您可能希望添加一个const重载,返回const Relation&
。