访问类成员的C++操作顺序

C++ order of operations accessing class member

本文关键字:操作 顺序 C++ 成员 访问      更新时间:2023-10-16

主线能工作吗?也许是其他运营商?有什么建议吗?我认为操作顺序是问题所在。必须使用b.addA("P")吗;b.R("P")。参考(b.R("P"))?

我想添加从一个对象到其他对象的引用,并在对象之间建立关系,就像数据库模型一样。

#include <iostream>
#include <vector>
#include <string>
class A;
class B;
class A{
std::string _name;
std::vector<A*> _refs;
public:
A(std::string="");
A& ref(A&);
std::string name() const;
};
class B{
std::string _name;
std::vector<A> _as;
public:
B(std::string="");
A& addA(std::string);
A& R(std::string);
};
A::A(std::string nm){
_name=nm;
}
A& A::ref(A &a){
for(int i=0; i<_refs.size(); i++)
if(_refs[i]==&a)
return a;
_refs.push_back(&a);
return a;
}
std::string A::name() const{
return _name;
}
B::B(std::string nm){
_name=nm;
}
A& B::addA(std::string nm){
for(int i=0; i<_as.size(); i++)
if(_as[i].name()==nm)
return _as[i];
_as.push_back(A(nm));
return _as[_as.size()-1];
}
A& B::R(std::string nm){
for(int i=0; i<_as.size(); i++)
if(_as[i].name()==nm)
return _as[i];
throw std::string("invaild A");
}
int main(){
B b;
b.addA("P").ref(b.R("P"));
return 0;
}

行能在主体工作吗?

当然。这里只有两个操作符,函数调用和引用(点操作符)。如果关联是从右向左的,或者函数调用的优先级高于引用,则会出现问题。事实并非如此。函数调用和引用具有相同的优先级,关联从左到右。这正是你想要的。

但是,您的代码有问题。它是成员函数B::A。在类B的上下文中,这将A的含义从class A更改为成员函数B::A(std::string)。对我来说,您的代码无法在多个编译器上编译,但它确实使用clang 3.1进行了编译对我来说,这看起来像是一个clang bug。(附录:这确实可以用clang编译,因为违反的规则是那些讨厌的"不需要诊断"规则之一。)你的代码是非法的;它(理想情况下)应该无法编译。

该函数的更好名称是findA。这个名称与类名不冲突,它使代码具有自文档性。

旁白:您可能需要考虑让该函数返回指针而不是引用。异常应用于异常事件(即错误)。(例如)"Foo"没有在向量中表示这一事实真的值得抛出异常吗?

从main中的行开始肯定会起作用。现在,这是如何发生的,这是一个你会感兴趣的问题?当你调用addA("P")时,它会创建类A的对象并通过引用返回它,现在,A的这个对象调用其成员fn ref(A&),正如你所看到的,你需要通过引用这个函数来传递A的对象,这个函数是通过调用b.R("P")来完成的,b.R本身返回对刚刚添加的字符串为"P"的对象的引用。现在你有

A'.ref(A")

其中A"A"是由B类的两个不同fn返回的引用对象(在这种情况下,通过dway,A"将是相同的)。

上面的调用将通过引用返回类A的另一个对象,您可以将其分配给类似的任何其他实例

A t;t=b.addA("P").ref(b.R("P));

您只是在执行链式函数调用,通过按引用返回对象,可以确保临时变量中不会发生任何可能丢失的事情。希望我已经回答了你的问题。