这是一个简单的单身人士:
class Singleton
{
Singleton();
virtual ~Singleton();
Singleton * Singleton::getInstance()
{
static Singleton * instance;
if (!instance) {
instance = new Singleton();
};
return instance;
};
}
Run Code Online (Sandbox Code Playgroud)
当主代码Singleton::getInstance()->someMethod()
第一次调用时,是不是实例化了两次类?会有内存泄漏吗?
我问,因为Visual Leak Detector检测到线路上的内存泄漏new Singleton()
.
几分钟前我问了一个关于单例实现的问题,我从@LightnessRacesinOrbit得到了非常好的答案.
但是我无法理解为什么在下一个例子中如果我Singleton
在变量中实例化inst
它的析构函数被调用两次?
#include <iostream>
class Singleton
{
public:
~Singleton() { std::cout << "destruction!\n"; }
static Singleton& getInstance()
{
static Singleton instance;
return instance;
}
void foo() { std::cout << "foo!\n"; }
private:
Singleton() { std::cout << "construction!\n"; }
};
int main()
{
Singleton inst = Singleton::getInstance();
inst.foo();
}
Run Code Online (Sandbox Code Playgroud)
输出:
construction!
foo!
destruction!
destruction!
Run Code Online (Sandbox Code Playgroud)
更正确的是,我理解为什么它会被调用两次.但是,如果在第一个析构函数之后,类的实例被销毁,我无法理解如何调用它两次?为什么没有例外?
还是没有被摧毁?为什么?
在论文P0135R0中有一个例子:
struct NonMoveable {
NonMoveable(int);
NonMoveable(NonMoveable&) = delete;
void NonMoveable(NonMoveable&) = delete;
std::array<int, 1024> arr;
};
NonMoveable make() {
return NonMoveable(42); // ok, directly constructs returned object
}
auto nm = make(); // ok, directly constructs 'nm'
Run Code Online (Sandbox Code Playgroud)
这困惑了我:
void NonMoveable(NonMoveable&) = delete;
Run Code Online (Sandbox Code Playgroud)
它是什么?构造函数如何无效?
UPD.有人联系了可能的答案 - 不!这个问题完全不同.
在Python中如何编写这样一个函数,它将使用给定的前缀调用当前文件中的所有函数?
例如:
def prepare(self):
# ??? to call prepare_1, prepare_2
def prepare_1(self):
def prepare_2(self):
Run Code Online (Sandbox Code Playgroud)
怎么写prepare
这样会调用所有函数启动prepare_
?
std::clamp
如果其中一个min
或max
参数是rvalues ,最好不要将返回值绑定到const ref .
典型的实现std::clamp
(非常简化):
template <class T>
constexpr const T& clamp(const T& value, const T& min, const T& max)
{
return value < min ? min : max < value ? max : value;
}
Run Code Online (Sandbox Code Playgroud)
正如已经在std :: clamp的cppreference中所述,当有人写道时会出现危险的情况:
int n = -1;
const int& r = std::clamp(n, 0, 255);
// r is dangling
Run Code Online (Sandbox Code Playgroud)
有没有办法编译时检测这些情况?
假设我们采用了一大堆unsigned char
s.
std::array<uint8_t, 100500> blob;
// ... fill array ...
Run Code Online (Sandbox Code Playgroud)
(注意:它已经对齐,问题不是关于对齐.)然后我们将其视为uint64_t[]
并尝试访问它:
const auto ptr = reinterpret_cast<const uint64_t*>(blob.data());
std::cout << ptr[7] << std::endl;
Run Code Online (Sandbox Code Playgroud)
uint64_t
对我来说,施放然后阅读它看起来很可疑.
但UBsan -Wstrict-aliasing
并没有触发它.Google在FlatBuffers中使用此技术.此外,Cap'n'Proto使用这个太.
是不确定的行为?
非常简化的示例(不必理会类A
和运算符在做什么,仅举例来说):
#include <iostream>
using namespace std;
template <bool is_signed>
class A {
public:
// implicit conversion from int
A(int a) : a_{is_signed ? -a : a}
{}
int a_;
};
bool operator==(A<true> lhs, A<true> rhs) {
return lhs.a_ == rhs.a_;
}
bool operator==(A<false> lhs, A<false> rhs) {
return lhs.a_ == rhs.a_;
}
int main() {
A<true> a1{123};
A<false> a2{123};
cout << (a1 == 123) << endl;
cout << (a2 == 123) << endl;
return 0;
} …
Run Code Online (Sandbox Code Playgroud) c++ templates implicit-conversion template-argument-deduction
template <class A>
struct Foo {
template <class Bar>
constexpr auto a_method();
};
template <class A>
template <class Bar>
constexpr auto Foo<A>::a_method() {
return 42;
}
template <>
template <class Bar>
constexpr auto Foo<void>::a_method() {
return 42;
}
Run Code Online (Sandbox Code Playgroud)
GCC可以编译这个。
但铿锵不能。错误输出:
<source>:15:27: error: conflicting types for 'a_method'
constexpr auto Foo<void>::a_method() {
^
<source>:4:18: note: previous declaration is here
constexpr auto a_method();
^
1 error generated.
Compiler returned: 1
Run Code Online (Sandbox Code Playgroud) UPD.有一个标记,它是这个问题的副本.但在那个问题中,OP问如何使用default
来定义纯虚拟析构函数.这个问题是关于有什么区别的.
在C++(如果可能的话,最新标准)中,使用空体实现定义纯虚拟析构函数和仅使用空体(或默认值)之间的真正区别是什么?
变式1:
class I1 {
public:
virtual ~I1() {}
};
Run Code Online (Sandbox Code Playgroud)
变式2.1:
class I21 {
public:
virtual ~I21() = 0;
};
I21::~I21() {}
Run Code Online (Sandbox Code Playgroud)
变式2.2:
class I22 {
public:
virtual ~I22() = 0;
};
I22::~I22() = default;
Run Code Online (Sandbox Code Playgroud)
更新我发现Variant 1和Variants 2.1/2.2之间至少有1个区别:
std::is_abstract::value
适用false
于变体1,true
适用于变体2.1和2.2.
可能有人可以发现2.1和2.2之间的区别?
是
std::optional<std::reference_wrapper<some_type>>
Run Code Online (Sandbox Code Playgroud)
是否符合C++ 17的标准(或草案)?
标准明确指出,std::optional
对于参考类型来说是不正确的.但它包括reference_wrapper
?
c++ ×9
c++17 ×3
singleton ×2
clamp ×1
clang ×1
destructor ×1
gcc ×1
memory-leaks ×1
optional ×1
pure-virtual ×1
python ×1
template-argument-deduction ×1
templates ×1