小编Fab*_*ica的帖子

重新抛出异常的自定义错误消息不是由what()打印的

我正在编写一组扩展的自定义异常std::exception.在某些代码中,当捕获异常时,我只是重新throw启动链,直到驱动程序main函数调用catches并打印结果.但是,最终打印的所有内容都是"std :: exception".这似乎不是我之前处理的范围问题.

为什么我的异常消息不能打印?

我的异常代码:

// General exception class
struct MyException : public std::exception
{
    std::string _msg;

    MyException(const std::string &exception_name) : _msg(exception_name) {}

    void setMessage(const std::string &message)
    {
        _msg += ": " + message + "\n";
    }

    void setLocation(const char * func, const char * file, const int line)
    {
        _msg += "  In function " + std::string(func) + "(" + file + ":" + std::to_string(line) + ")";
    }

    const …
Run Code Online (Sandbox Code Playgroud)

c++ exception throw

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

是否可以在C++中重置对另一个值的引用?

我知道通常在初始化之后重置参考是不可能的.

但是,我以某种方式尝试以下代码,它恰好适用于clang ++和g ++.

我的问题是,以下是一个有效的(行为定义的)C++?

std::string x = "x";
std::string y = "y";
std::string i = "i";
std::string j = "j";

// now references to x, y
std::pair<std::string &, std::string &> p { x, y };
p.first = "1"; //changes x
p.second = "2"; //changes y
// now references to i, j
new (&p) std::pair<std::string &, std::string &> {i, j};
p.first = "1"; //changes i
p.second = "2"; //changes j
Run Code Online (Sandbox Code Playgroud)

上面的代码适用于g ++和clang ++,但它是不是很好的C++?谢谢.

c++ reference placement-new c++11

12
推荐指数
2
解决办法
1833
查看次数

使用类类型向量的前向声明 - 不允许指向不完整类类型的指针

我有两节课,foobar.

foo.h #includes bar.h并包含一个std::vector指向bar对象的指针.在运行时期间的某个时刻,bar必须访问指向其他bar对象的指针向量.因此,foo包含一个getBarObjects()返回指针数组的方法.

因此,我foo在bar.h中转发声明.我显然还要转发声明我正在使用的方法 - foo::getBarObjects().当这返回指针数组时bar,我陷入了恶性循环.

我无法转发声明Bar然后只是转发声明getBarObjects(),因为这导致"不允许不完整的类型名称".

foo.h中:

#include "bar.h"
#include <vector>

class foo {
    public:
         foo();
         ~foo();
         std::vector<bar*> getBarObjects();
    private:
         std::vector<bar*> barObjects;
}
Run Code Online (Sandbox Code Playgroud)

bar.h:

class foo;
std::vector<bar*> foo::getBarObjects();        // error, doesn't know bar at this point

class bar {
    public:
        bar(foo *currentFoo);
        ~bar();
        bool dosth();
    private:
        foo *thisFoo;
}
Run Code Online (Sandbox Code Playgroud)

bar.cpp:

#include "bar.h"

bool bar(foo …
Run Code Online (Sandbox Code Playgroud)

c++ circular-dependency forward-declaration

11
推荐指数
2
解决办法
6764
查看次数

为什么当static_cast(ing)一个函数作废*时,编译器的行为会有所不同?

以下代码可在VSC ++ 2017中编译且没有任何错误,并且不会在gcc 7.3.0(error: invalid static_cast from type ‘int(int)’ to type ‘void*’ void* p = static_cast<void*>(func))中编译

#include <iostream>

int func(int x) { return 2 * x; }

int main() {

    void* p = static_cast<void*>(func);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ function-pointers void-pointers static-cast

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

为什么将set :: iterator而不是const_iterator传递给函数会违反“一个定义规则”?

cppreference.com给出std::set容器说明最后包含此注释:

成员类型,iterator并且const_iterator可以是同一类型的别名。因为iterator可以转换为const_iterator,所以const_iterator应该在函数参数列表中使用它,以避免违反“一个定义规则”。

我不明白这句话。据我了解,集合不允许修改其元素(如果需要更改一个元素,则必须先对其进行修改erase,然后再insert进行新的修改),因此每个集合都iterator可以作为const_iterator。该标准补充说,有可能(但不是必需)它们是同一类型。到目前为止,很明显。

我没有得到的是可能违反“ 一个定义规则”。该规则表示一个函数可以有许多声明,但只能有一个定义。如何违反?假设我有一个set<int>,并且创建了一个将迭代器作为参数的函数。由于它们的工作方式相同,因此我可以选择其类型:set<int>::iteratorset<int>::const_iterator。如果我听从建议,那会set<int>::iterator怎样?

我已经编写了一个程序来尝试找到答案。基本上有2个函数,一个函数接受an,另一个函数iterator接受a const_iterator,我分别调用了两次,一次传递了iterator一次,一次传递了一次const_iterator。这里是:

#include <iostream>
#include <set>

void print_set_iter(std::set<int>::iterator& it) {
    std::cout << "Set element from       iterator: " << *it       << "\n";
}

void print_set_const_iter(std::set<int>::const_iterator& const_it) {
    std::cout << "Set element from const_iterator: " << *const_it << …
Run Code Online (Sandbox Code Playgroud)

c++ iterator set parameter-passing one-definition-rule

9
推荐指数
2
解决办法
337
查看次数

ELF文件中的字符串如何编码?

我想证明密码很容易从程序中读取:

#include <stdio.h>
#include <string.h>

int main(int argc, char** argv)
{
    char password[] = "a big refreshing lemonade";
    return strcmp(argv[1], password);
}
Run Code Online (Sandbox Code Playgroud)

但是它不能按预期工作:

$ gcc foo.c
$ hexdump -C a.out | grep -C2 'lem'
000006c0  00 00 00 48 89 45 f8 31  c0 48 b8 61 20 62 69 67  |...H.E.1.H.a big|
000006d0  20 72 65 48 ba 66 72 65  73 68 69 6e 67 48 89 45  | reH.freshingH.E|
000006e0  d0 48 89 55 d8 48 b8 …
Run Code Online (Sandbox Code Playgroud)

c string elf

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

NaN 上的宇宙飞船运算符

在进行太空船比较操作时,C++ 如何处理浮点 NaN?我们知道通常的比较总是返回 false,那么 NaN 会如何改变呢?

std::numeric_limits<double>::quiet_NaN() <=> std::numeric_limits<double>::quiet_NaN()
Run Code Online (Sandbox Code Playgroud)

c++ nan language-lawyer spaceship-operator c++20

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

您将如何使用标准引号解释指向基类和派生类成员的指针的这种区别?

演示

#include<iostream>
struct A { int i = 10; };
struct B : A { };

int main(){
    std::cout << "decltype(&B::i) == int A::* ? " << std::boolalpha
              << std::is_same<decltype(&B::i), int A::*>::value << '\n';    //#1
    A a;
    std::cout << a.*(&A::i) << '\n';

    std::cout << "decltype(&B::i) == int B::* ? "
              << std::is_same<decltype(&B::i), int B::*>::value << '\n';    //#2
    B b;
    std::cout << b.*(&B::i) << '\n';
}
Run Code Online (Sandbox Code Playgroud)

代码打印

decltype(&B::i) == int A::* ? true
10
decltype(&B::i) == int B::* ? false …
Run Code Online (Sandbox Code Playgroud)

c++ pointer-to-member language-lawyer

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

何时在 C++ 中使用字符数组而不是字符串?

我们如何区分 C++ 中的字符数组和字符串?有什么 char 数组比 std::string 做得更好的吗?

c++ stdstring string-literals

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

为什么在 C++ 中需要“虚拟”和“=0”来描述一个方法是抽象的?

正如在C++ 编程语言中解释的那样:

virtual void push(char c) = 0;
virtual void pop() = 0;
Run Code Online (Sandbox Code Playgroud)

这个词virtual的意思是“以后可能会在这一个派生类中重新定义”
=0语法说,一些类来源于必须定义的功能。

那么为什么=0需要符号呢?是不是说派生类一定要定义这个函数,也就是说没有的时候=0,一些派生类就没有强制定义这个方法?

我对此感到困惑,需要一些帮助。

c++ virtual abstract-class derived-class pure-virtual

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