Questions tagged «c++»

有关C ++的问题,C ++是一种静态类型,自由格式,多范式,已编译的通用编程语言。

5
设计自上而下还是自下而上是更可取的?
据我了解,自上而下的设计是通过将抽象的高级概念细化为较小的混凝土和易于理解的部分,直到定义了最小的构建块。另一方面,自下而上定义了较低级别的部分,然后逐渐构建较高级别的块,直到形成整个系统。 实际上,最好将两种方法结合起来:从高级规范开始,以完全指定领域知识,其关系和约束。一旦清楚地了解了问题,便会创建最小的构建块来构建系统。 过程: 创建需求规范 创建设计规范(带有图表) 实行 交付 重复(在迭代开发中,我们不重复每个阶段的全部工作,而是重复每个阶段的一点工作,并每天开会以满足客户的动态需求) 看起来对我来说是完全正常的(以规格作为计划)。它有其缺陷,但这就是为什么我们要进行迭代开发:为什么要花时间在一个阶段上,而不是花时间进行需求分析,以研究领域知识中可能发生变化的所有可能事物(可能每天),而是进行一些分析,进行一些设计然后实施。 另一种方法是,每次迭代都是一种小型瀑布式的方式,在几天(或一周)内进行分析。设计同样如此。其余时间用于实施。自上而下的方法与迭代开发相结合有天生的错误吗? Paul Graham 在他的论文《自下而上编程》中似乎鼓励完全自下而上地构建,或者鼓励自下而上地对其进行编程,但是不建议进行需求分析/设计阶段: 经验丰富的Lisp程序员对程序进行了不同的划分。除自上而下的设计外,它们还遵循可称为自下而上的设计的原则-更改语言以适应问题。 就我所知,他的意思是Lisper仍然执行自上而下的设计,但程序自下而上,是真的吗?他写道: 值得强调的是,自下而上的设计并不意味着仅以不同的顺序编写相同的程序。自下而上工作时,通常会得到不同的程序。您将获得一种具有更多抽象运算符的更大语言,以及一个用它编写的较小程序,而不是一个单一的整体程序。取而代之的是门,而不是门。 这是否意味着在用Lisp编写程序期间,您最终会获得通用工具?
31 design  c++  lisp 

4
为什么在C ++中不隐式转换`void *`?
在C语言中,不需要将a强制转换void *为任何其他指针类型,因此始终可以安全地对其进行提升。但是,在C ++中并非如此。例如, int *a = malloc(sizeof(int)); 在C语言中有效,但在C ++中无效。(请注意:我知道您不应该malloc在C ++中使用,或者在这种情况下new,应该使用智能指针和/或STL;纯粹出于好奇而问)。为什么C ++标准不允许这种隐式转换,而C标准呢?


7
C ++程序是否应该捕获所有异常并防止异常冒泡过main()?
曾经有人告诉我,C ++程序最终应该捕获所有异常。当时给出的推理基本上是允许异常冒泡main()进入怪异的僵尸状态之外的程序。几年前有人告诉我,回想起来,我相信观察到的现象是由于有关项目中产生的异常大的堆芯产生了很长时间。 当时,这似乎很奇怪,但却令人信服。C ++应该“惩罚”程序员没有捕获所有异常完全是荒谬的,但是我面前的证据似乎支持了这一点。对于有问题的项目,引发未捕获异常的程序似乎确实进入了怪异的僵尸状态-或我怀疑是现在的原因,在意外的核心转储中的进程异常难以停止。 (对于任何想知道为什么这在当时不那么明显的人:该项目从多个进程的多个文件中生成了大量输出,这些输出有效地掩盖了任何形式的aborted (core dumped)消息,在这种情况下,对核心转储进行事后检查是没有必要的“这不是一项重要的调试技术,因此无需过多考虑核心转储。程序的问题通常不取决于寿命长的程序随时间推移从许多事件中累积的状态,而是取决于寿命短的程序的初始输入(< 1小时),因此使用来自调试版本或调试器的相同输入重新运行程序以获得更多信息更为实用。) 目前,我不确定仅出于防止异常离开的目的而捕获异常是否有任何主要的优点或缺点main()。 我可以想到的允许异常冒泡的小好处main()是,它会导致将结果std::exception::what()打印到终端上(至少使用Linux上的gcc编译程序)。另一方面,通过捕获所有派生自std::exception该异常的异常并打印结果来实现此目的很简单std::exception::what(),如果希望从非派生的异常中打印一条消息,std::exception则必须在离开之前对其进行捕获才能main()打印消息。 我可以想到的允许异常冒泡的适度缺点main()是,可能会生成不需要的核心转储。对于使用大量内存的过程而言,这可能会很麻烦,并且从程序控制核心转储行为需要特定于OS的函数调用。另一方面,如果需要核心转储和退出,则可以在任何时间通过调用来实现,而在std::abort()没有核心转储的情况下可以通过调用在任何时间实现std::exit()。 有趣的是,我认为我what(): ...在崩溃时从未见过由广泛分布的程序打印的默认消息。 支持或反对允许C ++异常冒出来的强有力的论据是什么(如果有)main()? 编辑:此站点上有很多常规异常处理问题。我的问题特别是关于无法处理的C ++异常,并使其一直存在main()-可能会显示错误消息,但这是立即显示的停止错误。
29 c++  exceptions 

5
C ++样式指南[关闭]
现在,我在C ++代码中使用了Google C ++样式指南,对此我感到非常满意。 最近有人告诉我,该指南非常糟糕:Google内部使用(我知道),该指南已经过时,并且推广了一些非常糟糕的做法。所以我想使用另一种编码风格。 有哪些良好且使用合理的C ++样式指南?我为gcc和Visual Studio编写代码,并且使用了许多C ++ 11功能。 我最喜欢Google C ++样式指南的是缩进,空格和命名约定(特别是所有类,类型(包括typedef,类型别名和模板别名)都以大写的首字母命名)。 我知道任何答案都是主观的(希望在此站点上可以),并且希望您提出任何意见,但我对最近使用的指南很感兴趣。

3
为什么C ++中的布尔类型支持++但不支持-?
为什么--布尔没有运算符,而布尔运算符却存在++呢? 我用C ++尝试过,不知道我的问题是否适用于另一种语言。我也很高兴知道。 我知道,我可以将运算符++与bool一起使用。它使布尔值等于true。 bool b = false; b++; // Now b == true. 为什么我们不能--相反地使用运算符? bool b = true; b--; // Now b == false; 它不是很有用,但我很好奇。

10
使用指针变量不是内存开销吗?
在C和C ++之类的语言中,使用指向变量的指针时,我们还需要一个内存位置来存储该地址。那这不是内存开销吗?如何补偿?时间紧迫的低内存应用程序中使用指针吗?
29 c++  c  pointers 


4
在开发过程中使用#ifdef在不同类型的行为之间切换
在开发过程中使用#ifdef在不同类型的行为之间进行切换是一种好习惯吗?例如,我想更改现有代码的行为,我有几个想法如何更改行为,并且有必要在不同的实现之间切换以测试和比较不同的方法。通常,代码更改很复杂,并且会影响不同文件中的不同方法。 我通常会介绍几个标识符并执行类似的操作 void foo() { doSomething1(); #ifdef APPROACH1 foo_approach1(); #endif doSomething2(); #ifdef APPROACH2 foo_approach2(); #endif } void bar() { doSomething3(); #ifndef APPROACH3 doSomething4(); #endif doSomething5(); #ifdef APPROACH2 bar_approach2(); #endif } int main() { foo(); bar(); return 0; } 这样就可以在不同的方法之间快速切换,并且仅用一份源代码即可完成所有操作。是发展的好方法还是更好的做法?

6
为什么不能检查互斥锁是否已锁定?
C ++ 14似乎省略了一种检查an是否std::mutex被锁定的机制。看到这样的问题: https://stackoverflow.com/questions/21892934/how-to-assert-if-a-stdmutex-is-locked 有几种解决方法,例如通过使用; std::mutex::try_lock() std::unique_lock::owns_lock() 但是这些都不是特别令人满意的解决方案。 try_lock()如果当前线程已锁定互斥锁,则允许返回假阴性,并且具有未定义的行为。它也有副作用。owns_lock()需要unique_lock在原始的基础上进行构造std::mutex。 显然我可以自己动手,但我宁愿了解当前界面的动机。 std::mutex::is_locked()对我来说,检查互斥对象状态的能力似乎并不神秘,因此我怀疑标准委员会故意忽略了此功能,而不是疏忽大意。 为什么? 编辑:好的,也许这个用例并不像我预期的那么普遍,所以我将举例说明我的特殊情况。我有一个分布在多个线程上的机器学习算法。每个线程异步运行,并在完成优化问题后返回到主池。 然后锁定主互斥锁。然后,该线程必须选择一个新的父代来从其变异后代,但只能从当前没有其他线程正在优化的后代的父代中选择。因此,我需要执行搜索以找到当前未被另一线程锁定的父母。由于主线程互斥锁已锁定,因此互斥锁的状态不会在搜索过程中发生变化。显然,还有其他解决方案(我目前正在使用布尔标志),但是我认为互斥锁为该问题提供了一种逻辑解决方案,因为它存在于线程间同步的目的。
28 c++ 


10
为什么我在了解C和C ++的情况下学习C ++ 11?[关闭]
我是C和C ++的程序员,尽管我不拘泥于两种语言,而是将两者混合编写。有时在类中包含代码,可能带有操作符重载或模板,如此出色的STL显然是一种更好的方法。有时,使用简单的C函数指针的可读性和清晰度要高得多。因此,我发现两种语言都具有美感和实用性。我不想讨论“如果将它们混合并使用C ++编译器进行编译,那么就不再是混合,而是所有C ++”,我想我们都理解混合它们的意思。另外,我不想谈论C与C ++,这个问题全都与C ++ 11有关。 C ++ 11引入了我认为对C ++的工作方式的重大更改,但是它引入了许多特殊情况,异常和不规则性,这些情况改变了不同功能在不同情况下的行为,对多重继承施加了限制,用作关键字的标识符,扩展字符串文字,lambda函数变量捕获等。 我知道在将来的某个时刻,当您说C ++时,每个人都会假定C ++ 11。就像如今您说C一样,您很可能是说C99。这使我考虑学习C ++ 11。毕竟,如果我想继续用C ++编写代码,可能只是因为我的同事在某些时候需要开始使用这些功能。 以C为例。经过这么多年,仍然有很多人在学习和编写C语言代码。为什么呢?因为语言很好。好的意思是,它遵循许多规则来创建好的编程语言。因此,除了功能强大(几乎所有编程语言都很容易实现或很难实现)之外,C还是常规的,几乎没有例外。但是,C ++ 11我不这么认为。我不确定C ++ 11中引入的更改是否会使该语言变得更好。 所以问题是:为什么我要学习C ++ 11?
28 learning  c++  c  c++11 

7
C ++技能高于C技能?[关闭]
我觉得经常看到的C / C ++并不能真正描述我在简历中的技能。因此,我计划将其分为高级C ++知识和普通C技能。 您认为这会让读者感到困惑吗?她可能会想:“ C是C ++的子集,那么这个人想打电话给我什么?” 好吧,我想告诉的是:我已经完成了几个真实的C ++项目,而纯粹的C项目只是一个业余爱好。您是否同意熟练的C ++程序员不一定是合格的C专家,或者您认为此转换很容易完成?
28 c++  c  skills 

3
为什么C ++模板错误消息如此恐怖?
C ++模板臭名昭著,因为它会生成冗长且无法读取的错误消息。我对C ++中的模板错误消息为何如此糟糕有一个大致的了解。本质上,问题在于直到编译器遇到模板中某种类型不支持的语法时才触发错误。例如: template <class T> void dosomething(T& x) { x += 5; } 如果T不支持该+=运算符,则编译器将生成一条错误消息。而且,如果这种情况发生在某处库的深处,则错误消息可能长达数千行。 但是C ++模板本质上只是一种编译时鸭子类型的机制。C ++模板错误从概念上讲非常类似于动态语言(例如Python)中可能发生的运行时类型错误。例如,考虑以下Python代码: def dosomething(x): x.foo() 在这里,如果x没有foo()方法,Python解释器将引发异常,并显示堆栈跟踪以及非常清楚的错误消息,指出问题所在。即使直到解释器深入某个库函数内部才触发错误,运行时错误消息也仍然不像典型的C ++编译器所发出的不可读呕吐那样糟糕。那么,为什么C ++编译器无法更清楚地指出出了什么问题?为什么某些C ++模板错误消息从字面上导致我的控制台窗口滚动5秒钟以上?

9
为什么Scala没有用C或C ++实现
有人知道为什么Scala是用Java和.NET而不是C或C ++实现的吗?大多数语言都是用Cor C ++实现的(例如Erlang,Python,PHP,Ruby,Perl)。除了允许访问Java和.NET库之外,用Java和.NET实现的Scala的优点是什么? 更新 如果用C来实现,Scala不会获得更多好处,因为它可以进行更好的调整而不是依赖JVM?
28 java  c++  .net  c  scala 

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.