在这种情况下,括号有什么好处?
What is the benefit of parentheses in that case?
我有一件简单的事情对我来说模棱两可。
Tea* mintTea = new Builder()->cup(2)->sugar(3)->flavour("mint")->build();
前面的代码给了我一个错误:C2440: 'initializing': cannot convert from 'Builder * to 'Tea *
.
但是当将括号放在new Builder()
代码时,代码运行良好。
Tea* mintTea = (new Builder())->cup(2)->sugar(3)->flavour("mint")->build();
完整代码:
class Tea;
class Builder {
public:
Builder() = default;
~Builder() = default;
int m_suger;
int m_cup;
string m_flavour;
Builder* sugar(int sugar);
Builder* cup(int cup);
Builder* flavour(string flavour);
Tea* build();
};
Builder * Builder::sugar(int sugar) {
this->m_suger = sugar;
return this;
}
Builder * Builder::cup(int cup) {
this->m_cup = cup;
return this;
}
Builder * Builder::flavour(string flavour) {
this->m_flavour = flavour;
return this;
}
Tea * Builder::build() {
return new Tea(this);
}
class Builder;
class Tea {
public:
int m_suger;
int m_cup;
string m_flavour;
Tea() = default;
Tea(Builder* b);
~Tea() = default;
};
Tea::Tea(Builder * b) {
m_suger = b->m_suger;
m_cup = b->m_cup;
m_flavour = b->m_flavour;
cout << "Hot " << b->m_cup << " cup of tea is comming!, with " << b->m_flavour << endl;
}
int main(int argc, char *argv[]) {
Tea* mintTea = (new Builder())->cup(2)->sugar(3)->flavour("mint")->build();
return 0;
}
在这种情况下,括号有什么好处?
如果没有括号,new Builder()->cup(2)->sugar(3)->flavour("mint")->build();
与新表达式的正确语法不匹配:
::(optional) new (placement_params)(optional) ( type ) initializer(optional) (1) ::(optional) new (placement_params)(optional) type initializer(optional) (2)
编译器会抱怨它,因为new Builder()->cup(2)->sugar(3)->flavour("mint")->build()
不能解释为有效的新表达式。如叮当声:
prog.cc:56:33: error: expected ';' at end of declaration
Tea* mintTea = new Builder()->cup(2)->sugar(3)->flavour("mint")->build();
^
;
然后编译器假设新表达式在new Builder()
后结束,然后给出错误消息说:
prog.cc:56:10: error: cannot initialize a variable of type 'Tea *' with an rvalue of type 'Builder *'
Tea* mintTea = new Builder()->cup(2)->sugar(3)->flavour("mint")->build();
^ ~~~~~~~~~~~~~
您编译器的错误消息(即C2440: 'initializing': cannot convert from 'Builder * to 'Tea *
(说同样的话。
使用括号可以正常工作,因为括号中新表达式的范围受到限制:
(new Builder())->cup(2)->sugar(3)->flavour("mint")->build();
// ~~~~~~~~~~~~~ the new expression; which returns a Builder*, and all the following code would work fine
运算符优先级。指针运算符->
的成员访问优先于运算符new
(不要与operator new()
混淆(。因此,有点令人困惑的是,表达式的值:
new Builder()->cup(2)->sugar(3)->flavour("mint")->build()
--实际上是Builder*
而不是Tea*
。这就是为什么你需要括号,所以首先执行new
,然后可以调用你的属性函数并返回一个Tea*
。
通过括号修复,这会泄漏内存:无法恢复new
返回的Builder*
值,因此无法delete
它。每次构建Tea
对象时,都会泄漏 2 个整数和一个字符串。
这两个问题的修复在运算符优先级表中:请注意,函数调用与成员访问的优先级相同,并且具有从左到右的关联性。因此,改用静态函数,确保 Builder 是可构造的,并按值返回:
class Builder {
public:
Builder() : m_sugar(0), m_cup(1), m_flavour("earl grey, hot") {}
static Builder get() { return Builder(); }
Builder sugar(int sugar) { m_sugar = sugar; return *this; }
Builder cup(int cup) { m_cup = cup; return *this; }
Builder flavour(string flavour) { m_flavour = flavour; return *this; }
Tea* pour() { Tea* hotCuppa = new Tea(this); return hotCuppa; }
private:
int m_sugar;
int m_cup;
string m_flavour;
};
现在你可以写:
Tea* tea42 = Builder::get().cup(2).sugar(3).flavour("mint").pour();
虽然除非你真的需要指向Tea
对象的指针,否则我不会使用工厂模式来构建指针:对于谁拥有指针会让人感到困惑。
编辑:@songyuanyao比我回答得更好,更准确。
- 在这种情况下,"typename..."意味着什么?
- 在这种情况下,int**在C中是什么意思
- 在这种情况下,括号有什么好处?
- 在这种情况下,#define 的作用是什么?
- 在这种情况下,我们可以使用静态而不是朋友吗,还有其他解决方案是什么
- 在这种情况下,删除指针数组期间会发生什么?
- 在这种情况下,有什么正确的方法可以实现锁定吗?
- 在这种情况下,* 有什么作用?:
- 在这种情况下,"使用"在做什么,正在存储什么?
- 在这种情况下,在"this"前面加上星号有什么作用?
- 在这种情况下,从左到右的结合性是什么意思
- 什么是错误C2039,在这种情况下它意味着什么
- 这个错误一般意味着什么?以及在这种情况下我如何解决它
- 编译器在这种情况下会做什么
- 在这种情况下,>=是什么意思
- 在这种情况下,溢出是什么意思
- 在这种情况下,为函数赋值有什么用
- 有人能向我解释一下在这种情况下发生了什么吗
- 在这种情况下,sizeof(int) 返回什么
- 警告C4309 -它是什么意思,在这种情况下可以忽略它