假设我有三个编译对象,都是由相同的编译器/版本生成的:
为简单起见,我们假设所有头文件都是用C++ 11编写的,只使用其语义在所有三个标准版本之间没有变化的构造,因此任何相互依赖性都用头包含正确表达,编译器没有反对.
这些对象的组合是什么,链接到单个二进制文件是不安全的?为什么?
编辑:欢迎涵盖主要编译器(例如gcc,clang,vs ++)的答案
我想用cmake和cpack为windows上的一些程序创建一个安装程序.我希望能够选择要安装的程序,所选程序将作为快捷方式显示在开始菜单中.这是一个简单的尝试.为每个程序完成了一个组件,但无法弄清楚如何生成开始菜单变量.现在,即使未选择安装它们,所有程序也始终在菜单中.首先是一个简单的程序安装.
#include <iostream>
#include <conio.h>
int main()
{
std::cout << "prog1" << std::endl;
_getch();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是CMakeLists.txt文件
cmake_minimum_required( VERSION 2.8 )
project ( CompoTest )
add_executable(prog1 prog1.cpp)
add_executable(prog2 prog2.cpp)
add_executable(prog3 prog3.cpp)
install(TARGETS prog1
RUNTIME DESTINATION bin
COMPONENT compo1)
install(TARGETS prog2
RUNTIME DESTINATION bin
COMPONENT compo2)
install(TARGETS prog3
RUNTIME DESTINATION bin
COMPONENT compo3)
set ( CPACK_PACKAGE_VERSION "1.0.0" )
set(CPACK_PACKAGE_EXECUTABLES
prog1 "prog 1"
prog2 "prog 2"
prog3 "prog 3"
)
set ( CPACK_COMPONENTS_ALL compo1 compo2 compo3 )
include (CPack)
Run Code Online (Sandbox Code Playgroud)
问题是生成开始菜单快捷方式取决于在安装中选择哪个程序我认为它应该很容易,但似乎不是.是否有可能做到这一点.
更新:我发现 …
我刚刚从C++ 14标准(我的重点)中读到了这个:
4.9浮动积分转换[conv.fpint]
1浮点类型的prvalue可以转换为整数类型的prvalue.转换截断; 也就是说,丢弃小数部分.如果截断的值无法在目标类型中表示,则行为未定义. [...]
这让我思考
float
值int
在截断后无法表示?(这取决于实施吗?)auto x = static_cast<int>(float)
不安全?float
来int
然后(假设你要截断)?我有一个类Foo,方法是isValid.然后我有一个方法bar()接收一个Foo对象,其行为取决于它是否有效.
为了测试这个,我想将一些对象传递给bar,其isValid方法总是返回False.由于其他原因,我无法在测试时创建Foo的对象,所以我需要一个对象来伪造它.我首先想到的是创建最通用的对象并向其添加属性isValid,以便将其用作Foo.但那不太奏效:
>>> foo = object()
>>> foo.isValid = lambda : False
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'isValid'
Run Code Online (Sandbox Code Playgroud)
我发现对象没有__dict__
,所以你不能为它添加属性.此时,我正在使用的解决方法是为此目的动态创建一个类型,然后创建该类型的对象:
>>> tmptype = type('tmptype', (), {'isValid' : lambda self : False})
>>> x = tmptype()
>>> x.isValid()
False
Run Code Online (Sandbox Code Playgroud)
但这似乎太长了一枪.必须有一些随时可用的通用类型,我可以用于此目的,但哪个?
我需要实现以下接口
struct mutex;
struct interface
{
//...
mutex& getMutex();
};
Run Code Online (Sandbox Code Playgroud)
我可以using mutex = ParticularMutex
在我的实现中使用直觉,但gcc告诉我:
error: conflicting declaration ‘using mutex = ’
error: ‘class mutex’ has a previous declaration as ‘class mutex’
Run Code Online (Sandbox Code Playgroud)
我没有定义任何两次,只是宣布两次,就像前面宣布的那样,所以
interface
?interface
定义?用template <typename mutex>
?我已经读过了std :: unique_ptr <T>需要知道T的完整定义吗?和unique_ptr转发声明?,但我的问题更具体.
以下编译:
// Compile with $ g++ -std=c++11 -c <filename>
#include <memory>
class A; // fwd declaration
class AUser
{
AUser(); // defined elsewhere
~AUser(); // defined elsewhere
std::unique_ptr<A> m_a;
};
Run Code Online (Sandbox Code Playgroud)
以下不是:
// Compile with $ g++ -std=c++11 -c <filename>
#include <memory>
class A; // fwd declaration
class AUser
{
AUser(); // defined elsewhere
~AUser(); // defined elsewhere
std::unique_ptr<A> m_a{nullptr};
};
Run Code Online (Sandbox Code Playgroud)
错误
$ g++ -std=c++11 -c fwd_decl_u_ptr.cpp
In file included from /usr/include/c++/4.7/memory:86:0,
from …
Run Code Online (Sandbox Code Playgroud) Stroustrup的The C++ Programming Language(第4版)中的§6.3.5.1的最后一句是:
如果数组或结构是,则默认初始化数组或类的成员.
但是,此测试显示默认初始化对象的未初始化成员(我也试过g++4.7 -std=c++11
)
#include <iostream>
struct Foo
{
int i;
Foo();
};
Foo::Foo() {}
int main()
{
Foo f;
std::cout << "f.i: " << f.i << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我必须遗漏一些东西,但有没有一个解释并不代表Stroustrup的肯定错误?
编辑:在答案之后,我理解默认初始化的概念应该包括在文本的其他部分中被称为未初始化的概念(例如,在§17.3.1中).这对我来说听起来很不清楚.实际上,使用未初始化来表示除"未明确用户初始化"之外的任何内容(就像在那里一样)是一个矛盾:有些东西是默认初始化但尚未初始化.除非有人放弃X和un-X分类相反的自然语言证据,否则排他性......
此外,同一部分(第6.3.5.1节)中的较早句子也是如此
默认情况下,局部变量[...]不会被初始化,除非它们是具有默认构造函数的用户定义类型[...]
这里的矛盾再次明显.接受第一个和后一个语句都是真的意味着存在同时默认初始化且默认情况下未初始化的变量(即局部变量).
恕我直言,这充其量是一种非常不清楚的自然语言用来描述某些东西.
在过去,如果我想要一个对象的字符串表示A
,我会写一些带有签名的东西,void to_string(const A& a, string& out)
以避免额外的副本.这仍然是C++ 11中的最佳实践,具有移动语义和所有?
我已经阅读了一些关于其他上下文的评论,这些评论建议依赖于RVO而不是写作string to_string(const A& a)
.但RVO并不能保证会发生!那么,作为to_string的程序员,我怎么能保证字符串不会被不必要地复制(独立于编译器)?
copy return-by-reference move-semantics c++11 return-by-value
使用gcc(这里是4.7.2)我收到有关未使用的自动变量的警告,但没有关于其他变量的警告:
// cvars.h
#ifndef CVARS_H_
#define CVARS_H_
const auto const_auto = "const_auto";
const char const_char_array[] = "const_char_array";
const char * const_char_star = "const_char_star";
const char use_me = 'u';
#endif // CVARS_H_
//---
//comp_unit.cpp
#include "cvars.h"
void somef()
{
//const_auto // commented out - unused
use_me; // not using any of the others either
}
// compile with $ g++ -std=c++11 -Wunused-variable -c comp_unit.cpp
// gcc outputs warning: ‘cvars::const_auto’ defined but not used [-Wunused-variable]
// but does not complain about the …
Run Code Online (Sandbox Code Playgroud) 我有一个带有原始指针的情况,我无法更改为智能指针,因为它是接口的一部分(我不想破坏使用它的任何代码):
struct Foo
{
Foo();
~Foo();
int * m_pStuff; // public!
};
Run Code Online (Sandbox Code Playgroud)
我不想在我的病人身上做太多事情.就像这样:
m_pStuff = new int[dynamically_obtained_size_which_is_greater_than_0];
m_pStuff[0] = 0;
Run Code Online (Sandbox Code Playgroud)
然后在析构函数中删除它.
现在,我想知道使用try/catch是否值得围绕它:
Foo::Foo()
: m_pStuff(0)
{
try
{
m_pStuff = new int[dynamically_obtained_size_which_is_greater_than_0];
m_pStuff[0] = 0;
}
catch(...)
{
delete m_pStuff;
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
我能看到的观点:
我能看到的要点:
我还是很犹豫:我是否应该尝试使用try/catch?为什么?我想就此提出你的意见.
此外,您是否看到在分配时由于内存不足而导致异常的可能性?在这种情况下,已经分配的内存将被自动回收,对吗?
谢谢!
c++ constructor pointers exception dynamic-memory-allocation