小编mic*_*c_e的帖子

如何在类子类化时运行代码?

当我的类被子类化时,有没有办法触发代码?

class SuperClass:
    def triggered_routine(subclass):
        print("was subclassed by " + subclass.__name__)

magically_register_triggered_routine()

print("foo")

class SubClass0(SuperClass):
    pass

print("bar")

class SubClass1(SuperClass):
    print("test")
Run Code Online (Sandbox Code Playgroud)

应输出

foo
was subclassed by SubClass0
bar
test
was subclassed by SubClass1
Run Code Online (Sandbox Code Playgroud)

python inheritance

95
推荐指数
2
解决办法
6416
查看次数

是否可以在命名空间中放置标准的纯C头#include指令?

可能重复:
在命名空间块中包装#include是个好主意吗?

log在全局命名空间(::log)中有一个带有类的项目.

因此,自然地,之后#include <cmath>,编译器在每次尝试实例化我的日志类的对象时都会给出错误消息,因为<cmath>使用许多三字母方法污染全局命名空间,其中一个是对数函数log().

因此,有三种可能的解决方案,每种解决方案都有其独特的丑陋副作用.

  • 将日志类移动到它自己的命名空间,并始终使用它的完全限定名称访问它.我真的想避免这种情况,因为记录器应尽可能方便使用.
  • 编写一个mathwrapper.cpp文件,它是项目中唯一包含的文件<cmath>,并<cmath>通过包装器提供所有必需的功能namespace math.我不想使用这种方法,因为我必须为每个必需的数学函数编写一个包装器,它会增加额外的调用惩罚(部分由-flto编译器标志取消)
  • 我正在考虑的解决方案:

更换

#include <cmath>
Run Code Online (Sandbox Code Playgroud)

通过

namespace math {
#include "math.h"
}
Run Code Online (Sandbox Code Playgroud)

然后通过计算对数函数math::log().

我已经尝试过了,确实可以按预期编译,链接和运行.但它确实有多个缺点:

  • 它(显然)不可能使用<cmath>,因为<cmath>代码通过其完全限定的名称访问函数,并且不推荐在C++中使用它.
  • 我对它有一种非常非常糟糕的感觉,就好像我会受到猛禽的攻击和活着.

所以我的问题是:

  • 是否有任何建议/约定/等禁止在名称空间中包含指令?
  • 可能有什么问题

    • 不同的C标准库实现(我使用glibc),
    • 不同的编译器(我使用g ++ 4.7,-std = c ++ 11),
    • 链接?
  • 你有没有试过这样做?
  • 有没有其他方法可以从全局命名空间中消除数学函数?

我在stackoverflow上发现了几个类似的问题,但大多数是关于包含其他C++头文件,这显然是一个坏主意,而那些没有关于C库链接行为的矛盾陈述.另外,额外放入#include <math.h>内部extern "C" {}是否有益?

编辑

因此,我决定做其他人正在做的事情,并将我的所有代码放在项目命名空间中,并在包含时使用它的完全限定名称访问记录器<cmath>.

c++ namespaces include

13
推荐指数
2
解决办法
2134
查看次数

在C++引用中,&符号的语义准确位置是什么

非常常见的是,声明指针的语义准确方法是

int *x;
Run Code Online (Sandbox Code Playgroud)

代替

int* x;
Run Code Online (Sandbox Code Playgroud)

这是因为C看作*x是一个int,而不是x一个int指针.

这很容易证明

int* a, b;
Run Code Online (Sandbox Code Playgroud)

其中a是int指针,而bint是int.

stackoverflow.com上至少有5个重复的问题,讨论这个问题的指针.但是参考文献怎么样?

c++ reference

11
推荐指数
3
解决办法
1699
查看次数

如何在C++(gcc)中获取完全限定的函数名,_excluding_返回类型?

此问题描述了如何使用__PRETTY_FUNCTION__获取函数的全名,包括其返回类型,参数类型,命名空间和模板参数.

考虑以下,美丽的功能:

namespace foo {
namespace {

template<int i>
int (*bar(int (*arg)(int *)))(int *) {
    printf("%s\n", __PRETTY_FUNCTION__);

    return arg;
}

} // anonymous namespace
} // namespace foo
Run Code Online (Sandbox Code Playgroud)

如果你不明白,该函数接受并返回一个指向int *- > int函数的指针.

g++(4.9)编译时,它的名字很漂亮,

int (* foo::{anonymous}::bar(int (*)(int*)))(int*) [with int i = 1337]
Run Code Online (Sandbox Code Playgroud)

并且,clang++(3.5),

int (*foo::(anonymous namespace)::bar(int (*)(int *)) [i = 1337])(int *)
Run Code Online (Sandbox Code Playgroud)

这些字符串非常不适合测试函数是否是某个命名空间的一部分.有没有其他方法,或者说,编译器提供的库来解析这些字符串?

为了澄清,我宁愿有类似的东西

foo::{anonymous}::bar <I don't care about anything beyond this point>
Run Code Online (Sandbox Code Playgroud)

更理想的是,我想要一种编译时的方式,比如一个产生某种列表的constexpr函数split(__PRETTY_FUNCTION__)

  • 完全限定的功能名称
  • 返回类型
  • arg0的类型 …

c++ gcc

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

在recvfrom系统调用期间取消C++ 11 std :: thread?

我正在使用C++ 11 std :: thread.它的主循环包括一个阻塞的recvfrom()调用,它监听到达DATAGRAM套接字的UDP数据包,以及一些复杂的代码,用于解析消息并在进程中处理大量的STL容器.

该线程属于一个class(helloexchange),由构造函数启动,应该在析构函数中取消.出于显而易见的原因,我不想强​​行终止线程,因为这可能会破坏数据结构,这些数据结构部分位于类之外.

当使用pthread而不是时std::thread,有一种pthread_cancel方法,它与pthread_setcancelstate我一起提供了我需要的所有功能:它只会在某些系统调用中阻塞时取消线程,并且对于某些部分可以完全禁用取消.一旦再次启用取消,则执行取消.这是工作pthread代码的完整示例:

#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <cstdio>
#include <pthread.h>
#include <net/if.h>
#include <ifaddrs.h>

int sock;

void *tfun(void *arg) {
    std::cout << "Thread running" << std::endl;
    while(true) {
        char buf[256];
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        socklen_t addrlen = sizeof(addr);
        //allow cancelling the thread
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

        //perform the blocking recvfrom syscall
        int size = recvfrom(sock, (void *) …
Run Code Online (Sandbox Code Playgroud)

c++ linux pthreads c++11

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

使用具有非空读缓冲区的套接字流时出现"非法搜索"错误

我正在编写一个Linux x86_64使用的服务器应用程序<sys/socket.h>.接受连接后accept(),我fdopen()用来将检索到的套接字包装成FILE*流.

写入和读取该FILE*流通常可以很好地工作,但是当它写入时,套接字变为不可用,同时它具有非空的读取缓冲区.

出于演示目的,我编写了一些侦听连接的代码,然后逐行读取输入到读缓冲区中fgetc().如果该行太长而无法放入缓冲区,则它不会被完全读取,而是在下一次迭代期间读取.

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

FILE* listen_on_port(unsigned short port) {
        int sock = socket(AF_INET, SOCK_STREAM, 0);
        struct sockaddr_in name;
        name.sin_family = AF_INET;
        name.sin_port = htons(port);
        name.sin_addr.s_addr = htonl(INADDR_ANY);
        if(bind(sock, (struct sockaddr*) &name, sizeof(name)) < 0)
                perror("bind failed");
        listen(sock, 5);
        int newsock = accept(sock, 0, 0);
        return fdopen(newsock, "r+");
}

int main(int argc, char** argv) {
        int bufsize …
Run Code Online (Sandbox Code Playgroud)

c sockets linux fdopen

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

将Java资源作为文件访问

我正在尝试从类路径/ JAR文件中访问资源作为File对象.我知道它是使用InputStream对象的首选方法,但我使用的是需要File对象的外部库(WorldEdit).

这是我的代码:

InputStream templStream = "".getClass().getResourceAsStream("/res/template.prom");
System.out.println("templateStream: " + templStream.toString());
File templFile = new File("".getClass().getResource("/res/template.prom").toURI());
System.out.println("templateFile: " + templFile.canRead());
Run Code Online (Sandbox Code Playgroud)

现在,当我还在Eclipse中时,访问资源的两种方式都可以完美地工作并产生这样的输出:

templStream: java.io.BufferedInputStream@746d1683
templFile: true
Run Code Online (Sandbox Code Playgroud)

但是在将代码导出到JAR存档后,代码将失败:

templStream: sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@47aa261b
Exception in thread "main" java.lang.IllegalArgumentException: URI is not hierarchical
    at java.io.File.<init>(File.java:392)
    at SMCToPROM.main(SMCToPROM.java:101)
Run Code Online (Sandbox Code Playgroud)

所以我一直没有成功地寻找一种方法来直接访问资源作为文件,或者使用InputStream并将该InputStream转换为文件.

最糟糕的情况是回退解决方案是将InputStream复制到文件系统上的文件,然后打开该文件,但我希望这不是必要的.

java resources inputstream file

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

如何将指针(或引用)存储到std :: set中的对象

在C++ 11 STL中是否有任何适当的方法来存储对象指针std::set,并通过对象的operator <方法对它们进行适当的排序?

当然,有可能编写我自己的Compare类型并将其传递给set作为其第二个模板参数,但我认为STL将提供更方便的方式.

一些谷歌搜索透露std::reference_wrapper,在我看来应该允许这样的代码:

#include <functional>
#include <set>

struct T {
    int val;
    bool operator <(T& other) {
        return (this->val < other.val);
    }
};

int main() {
    std::set<std::reference_wrapper<T>> s;
    T a{5};
    s.insert(a);
}
Run Code Online (Sandbox Code Playgroud)

但事实上,这会导致编译器错误:

clang++ -std=c++11 -Wall -Wextra -pedantic test.cpp -o test
In file included from test.cpp:1:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/functional:49:
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/bits/stl_function.h:235:20: error: invalid operands to binary expression ('const std::reference_wrapper<T>'
      and 'const std::reference_wrapper<T>')
      { return __x < …
Run Code Online (Sandbox Code Playgroud)

c++ stl

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

C预处理器:__ COUNTER__的自己实现

我目前正在使用__COUNTER__我的C库代码中的宏来生成唯一的整数标识符.它工作得很好,但我看到两个问题:

  • 它不是任何C或C++标准的一部分.
  • 也使用的独立代码__COUNTER__可能会混淆.

因此,我希望实现与__COUNTER__我自己的等价物.

我所知道的,但替代品并不需要使用:

  • __LINE__ (因为每行多个宏不会获得唯一ID)
  • BOOST_PP_COUNTER(因为我不想要boost依赖)

BOOST_PP_COUNTER证明这可以做到,即使其他答案声称这是不可能的.

本质上,我正在寻找一个头文件"mycounter.h",这样

#include "mycounter.h"

__MYCOUNTER__
__MYCOUNTER__ __MYCOUNTER__
__MYCOUNTER__
Run Code Online (Sandbox Code Playgroud)

将进行预处理gcc -E,以

(...)

0
1 2
3
Run Code Online (Sandbox Code Playgroud)

不使用内置__COUNTER__.

注:此前,这个问题被标记为重复这个,它使用交易__COUNTER__,而不是回避它.

c macros c-preprocessor

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

使用 mingw32 构建时与 cygwin1.dll 链接?

我希望以尽可能少的工作量将 Linux C++ 应用程序移植到 Windows(即根本没有代码修改,也没有全新的构建系统)。

该应用程序主要对SDL和进行 API 调用OpenGL,这两者都在 Windows 上可用。但是,它也使用了POSIX诸如 ptys 之类的功能,这些功能阻止了我使用mingw32工具链。

Cygwin,或者更准确地说,cygwin1.dll实现整个POSIXAPI 并在内部将其转换为Win32. 我知道它Cygwin也带有自己的编译器套件,但据我所知,不可能直接调用Win32或其他 Windows 库(例如SDLOpenGL)。

因此,我的想法是使用mingw32(在大多数发行版上也可以方便地作为交叉编译器使用)构建项目,但此外还与cygwin1.dll. 然而,我开始怀疑互联网上似乎没有人尝试过这一点,而且 cygwin 编译器在 Linux 上似乎不可用。

所以我的问题是:

  • 这是一个合法的想法,还是即使我设法将其破解,一切都会失败吗?
  • 这样做的合法方法是什么(我从哪里获得 cygwin 头文件和 dll 文件)?

许可不是问题。

c++ dll cygwin cross-platform mingw

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