我寻求建议是否使用./*这对 - > / this, 即C ++(* this).chained()。methods()与this-> chained() - > methods()。
顺便说一句,目前我见过的大部分页面都是推荐的 [[C ++(* this).chained()。methods()]]。
我只是想知道,因为你做不到
My_Class object.chained()。methods();
(顺便说一下,我没有在第一部分中测试过这些例子。我在第二部分提供了测试的例子。)
你必须
My_Class对象;
object.chained()方法();
这是一个恼人的额外行
或者你可以做到
My_Class object = My_Class().object.chained().methods();
需要值复制 - 如果构造函数有副作用,则不能接受,比如注册对象实例 - 就像许多Knobs库那样
或者你可以做到
My_Class* object_ptr = *(new My_Class).object.chained().methods();
有效,但需要烦人的*(ptr)
或者你可以做到
My_Class* object_ptr = (new My_Class)->object.chained()->methods();
这是一个更好的十分。
我想你可以做到
My_Class&安培; object_ref(。My_Class()链()方法());
我不确定我对此的看法。
顺便说一下,我这里不需要调试帮助 我一直在编写这样的东西 我仅为了清楚起见提供了示例。
我正在寻求样式建议,因为有几种方法可以编写它, 我使用了不同的库,以相反的方式完成它。
混合它们很难看:
My_Object_with_Setters* object_ptr2 = &((new My_Object_with_Setters)->set_R1(1).set_P1(2)->set_R1(3))
My_Object().method_returning_ptr()->method_returning_ref();
也许它不是那么糟糕......但肯定会让人感到困惑。
当我遇到使用混合.chained() - >方法()的两个不同库的代码时 我有时希望能够使用后缀地址和解除引用运算符
My_Object * mptr = My_Object()。method_returning_ptr() - > method_returning_ref - >&
我经常将这个习惯用于setter函数
class My_Object_with_Setters {
public:
static int count;
int value;
public:
My_Object_with_Setters() {
++count;
value = 0;
}
public:
std::ostream& print_to_stream(std::ostream& ostr) const {
ostr << "(" << this->count << "," << this->value << ")";
return ostr;
}
friend std::ostream&
operator<< (
std::ostream& ostr,
const My_Object_with_Setters& obj ) {
return obj.print_to_stream(ostr);
}
public:
My_Object_with_Setters& set_R1(int val) {
this->value = val;
std::cout << "set_R1: " << *this << "\n";
return *this;
}
My_Object_with_Setters& set_R2(int val) {
this->value = val;
std::cout << "set_R2: " << *this << "\n";
return *this;
}
public:
My_Object_with_Setters* set_P1(int val) {
this->value = val;
std::cout << "set_P1: " << *this << "\n";
return this;
}
My_Object_with_Setters* set_P2(int val) {
this->value = val;
std::cout << "set_P2: " << *this << "\n";
return this;
}
public:
My_Object_with_Setters set_V1(int val) {
this->value = val;
std::cout << "set_V1: " << *this << "\n";
My_Object_with_Setters retval;
retval = *this; // kluge to force new object
return retval;
}
My_Object_with_Setters set_V2(int val) {
this->value = val;
std::cout << "set_V2: " << *this << "\n";
My_Object_with_Setters retval;
retval = *this; // kluge to force new object
return retval;
}
};
int My_Object_with_Setters::count = 0; // clas static, distinguishes instances
void test_My_Object_with_Setters()
{
std::cout << "cascading ref, ref, copy, copy, ref, ref\n";
My_Object_with_Setters object;
object.set_R1(1).set_R2(2).set_V1(11).set_V2(12).set_R1(101).set_R2(102);
std::cout << "cascading ptr, ptr, ptr, ptr\n";
My_Object_with_Setters* object_ptr = (new My_Object_with_Setters)->set_P1(1)->set_P2(2)->set_P1(11)->set_P2(12);
std::cout << "cascading &address-of, ptr, ptr\n";
(&object)->set_P1(1)->set_P2(2);
std::cout << "cascading new ptr ref ptr ref\n";
My_Object_with_Setters* object_ptr2 = &(*(new My_Object_with_Setters)->set_R1(1).set_P1(2)).set_R1(3);
}
测试输出:
cascading ref, ref, copy, copy, ref, ref
set_R1: (1,1)
set_R2: (1,2)
set_V1: (1,11)
set_V2: (2,12)
set_R1: (3,101)
set_R2: (3,102)
cascading ptr, ptr, ptr, ptr
set_P1: (4,1)
set_P2: (4,2)
set_P1: (4,11)
set_P2: (4,12)
cascading &address-of, ptr, ptr
set_P1: (4,1)
set_P2: (4,2)
cascading new ptr ref ptr ref
set_R1: (5,1)
set_P1: (5,2)
set_R1: (5,3)
class My_Object {
public:
static int count;
public:
My_Object() {
++count;
}
public:
My_Object& method1_returning_ref_to_current_object() {
std::cout << count << ": method1_returning_ref_to_current_object\n";
return *this;
}
My_Object& method2_returning_ref_to_current_object() {
std::cout << count << ": method2_returning_ref_to_current_object\n";
return *this;
}
public:
My_Object* method1_returning_ptr_to_current_object() {
std::cout << count << ": method1_returning_ptr_to_current_object\n";
return this;
}
My_Object* method2_returning_ptr_to_current_object() {
std::cout << count << ": method2_returning_ptr_to_current_object\n";
return this;
}
public:
My_Object method1_returning_value_copy_of_current_object() {
std::cout << count << ": method1_returning_value_copy_of_current_object\n";
My_Object retval;
return retval;
}
My_Object method2_returning_value_copy_of_current_object() {
std::cout << count << ": method2_returning_value_copy_of_current_object\n";
My_Object retval;
return *this;
}
};
int My_Object::count = 0; // clas static, distinguishes instances
void test_My_Object()
{
std::cout << "cascading ref, ref, copy, copy, ref, ref\n";
My_Object object;
object
.method1_returning_ref_to_current_object()
.method2_returning_ref_to_current_object()
.method1_returning_value_copy_of_current_object()
.method2_returning_value_copy_of_current_object()
.method1_returning_ref_to_current_object()
.method2_returning_ref_to_current_object()
;
std::cout << "cascading ptr, ptr, ptr, ptr\n";
My_Object* object_ptr = new My_Object;
object_ptr
->method1_returning_ptr_to_current_object()
->method2_returning_ptr_to_current_object()
->method1_returning_ptr_to_current_object()
->method2_returning_ptr_to_current_object()
;
std::cout << "cascading &address-of, ptr, ptr\n";
(&object)
->method1_returning_ptr_to_current_object()
->method2_returning_ptr_to_current_object()
;
std::cout << "cascading new ptr ref ptr ref\n";
My_Object* object_ptr2
= (&(*(new My_Object)
->method1_returning_ptr_to_current_object())
.method2_returning_ref_to_current_object())
;
}
测试输出
cascading ref, ref, copy, copy, ref, ref
1: method1_returning_ref_to_current_object
1: method2_returning_ref_to_current_object
1: method1_returning_value_copy_of_current_object
2: method2_returning_value_copy_of_current_object
3: method1_returning_ref_to_current_object
3: method2_returning_ref_to_current_object
cascading ptr, ptr, ptr, ptr
4: method1_returning_ptr_to_current_object
4: method2_returning_ptr_to_current_object
4: method1_returning_ptr_to_current_object
4: method2_returning_ptr_to_current_object
cascading &address-of, ptr, ptr
4: method1_returning_ptr_to_current_object
4: method2_returning_ptr_to_current_object
cascading new ptr ref ptr ref
5: method1_returning_ptr_to_current_object
5: method2_returning_ref_to_current_object
顺便说一下,我这里不需要调试帮助。我仅为了清楚起见提供了示例。
我正在寻求时尚建议。
答案 0 :(得分:6)
每个人都有自己的风格;正如你所说,当你开始混合它们时,它真的很烦人。
就个人而言,我只返回一个函数的指针,如果它可能是0; this
永远不会为0,所以我总是会返回*this
(即引用),因此会与.
链接。
对于它的价值,我也非常努力地使默认构造函数变得便宜,部分原因是因为有很多情况下它首先默认构造然后分配是方便的。
答案 1 :(得分:2)
我能给出的最佳答案是“保持一致”。如果您的其余代码使用this->
,请使用该代码。如果它使用(*this).
,请使用它。
由于差异只是语法糖,因此您最好的指导就是您使用的其他代码。我认识的大多数人都更喜欢->
语法,但是如果你要集成到现有的库中,你可能想跳过它。
就个人而言,我会使用额外的初始化方法。它对我来说是最干净的,一行构造堆栈上的对象,其他行根据需要调用方法。如果你只需要这些方法并且它们不依赖于实际的对象,我会将它们设置为静态并一起跳过对象。