小编Dmi*_*y J的帖子

Scott Meyers建议偏爱非成员非朋友方法是否适用于对象构建?

假设我有一节课:

class C{
  int x_;
  int y_;
public:
  C(int x, int y): x_(x), y_(y){}
};
Run Code Online (Sandbox Code Playgroud)

然后我想从一个字符串添加构造,它只是解析xy.在阅读迈耶斯的书之前,我通常会在课堂上将它作为另一个构造函数C.但是,它也可以使其成为非会员非朋友:

C CFromString(const std::string& s){
  int x, y;
  //...parse them somehow, throw exception if needed...
  return C(x,y);
}
Run Code Online (Sandbox Code Playgroud)

对我来说,这是许多"值类"的标准情况,当有一个"主"构造函数将私有成员设置为提供的值(可能检查正确性).这些类的其他构造函数通常只是从其他一些参数计算这些值.

在我的例子中,使这样的构造函数成为非成员非朋友有什么缺点吗?

UPD.我理解Meyers的建议,以及NMNF功能的优点.在他的书中没有关于NMNF对象构造的例子,所以我想确保他的建议也适用于建筑.

c++ constructor

7
推荐指数
2
解决办法
340
查看次数

在 C++ 中什么可以(什么不能)抛出异常?

是否存在可能导致 C++ 异常的“代码语句”的完整列表(可能是递归定义的)?像这样的东西:

1)throw声明(自然)

2) 调用new

3) 调用标准库中记录为能够抛出异常的任何函数。

4) 调用包含 1-3 操作的任何用户定义函数(包括构造函数)。

5)还有别的事吗?在堆栈上分配本地对象、对内置类型的操作、取消引用指针、类型转换 - 它们能够抛出异常吗?

6) 其他一切均无异常。

我所说的无异常并不是指总是成功的操作。取消引用指针肯定不是。但将其包装在块中仍然没有意义try-catch,考虑函数取消引用指针的异常安全性等。因此,成功或导致未定义行为的代码可以被视为无异常。

更新。尽管我写了最后一段,但我仍然得到了一条评论,即未定义的行为也可能抛出,所以让我解释一下我的意思。考虑以下代码:

void bar();
Class C{
...
public:
  foo() {
    something_that_breaks_class_invariants;
    bar();
    something_that_restores_class_invariants;
  }
}
Run Code Online (Sandbox Code Playgroud)

如果我正确理解异常安全是什么,那么如果bar()可以抛出异常,那么这段代码就很糟糕。我应该改变语句的顺序,或者我应该包装bar()try-catch块中,恢复类不变量并进一步传播异常。

但是,如果 bar() 成功返回或导致未定义的行为(因为,我不知道,其他东西被破坏了),那么就foo()可以了。foo()不能做任何事情,也不应该关心 可能的未定义行为bar()。从这个意义上讲bar()是无异常的,可以标记的noexcept,等等。

所以我的问题是:什么样的语句可以认为bar()它是无异常的?

c++ exception

5
推荐指数
1
解决办法
1185
查看次数

c ++是否有STL算法来检查范围是否严格排序?

"严格地"是指"没有相同的元素".

is_sorted(v.begin(), v.end(), std::less<>()) 
Run Code Online (Sandbox Code Playgroud)

不符合我的目标,因为它对于像这样的范围返回true 1,2,2,4,5.

is_sorted(v.begin(), v.end(), std::less_equal<>()) 
Run Code Online (Sandbox Code Playgroud)

将根据这里给出的实现工作,但不幸的是is_sorted要求Compare谓词是严格的排序(Compare(a,a)必须是假的),std::less_equal当然不是.

那么我应该为此目的编写自己的循环吗?

c++ stl

3
推荐指数
1
解决办法
756
查看次数

是否可以在c ++中强制传递依赖对象的constness

这是我想要阻止的:

class Dep; //for "dependency"

class C {
  private: 
    const Dep& dep_; //or std::shared_ptr if I want to guarantee proper lifetime of dependency
  public:
    C(const Dep& dep) : dep_(dep){}
}

Dep d(Arg arg);
C obj(d); //obj can't change d
d.some_non_const_method(); //But it's creator can :(
Run Code Online (Sandbox Code Playgroud)

我想得到的是,创建C对象的唯一正确方法是这样的:

Dep d(Arg arg);
d.some_non_const_method();
const Dep d1(d); //or move constructor if appropriate
C obj(d1); //Object d1 must be const!
d1.some_non_const_method(); //compile error, so obj can be sure that the dependency he's got …
Run Code Online (Sandbox Code Playgroud)

c++ dependency-injection const

3
推荐指数
1
解决办法
88
查看次数

std :: transform一元操作签名

我对std :: transfrom 的以下描述感到困惑:

unary_op - 将应用的一元操作函数对象.函数的签名应该等同于以下内容:

Ret fun(const Type &a);

签名不需要const &.

这两个陈述似乎是矛盾的.有人可以澄清这里的意思吗?如果签名是会发生什么Ret fun(Type a)Ret fun(Type&& a)Ret fun(Type& a)

c++ stl

3
推荐指数
1
解决办法
83
查看次数

是否保证标准提取运算符>>在失败的情况下不会改变参数?

如果在调用像input_stream >> i;这里i是算术型,抛出异常或设置badbit等,是保证i并没有改变?

c++ extraction-operator

1
推荐指数
1
解决办法
76
查看次数