4

我曾在一些中型项目上使用 C++,但我从未用 C 进行过任何认真的编程。

阅读这篇文章后,我开始想知道如何在没有类和异常的情况下使用 C++11。我曾经听说过clean C这个词。Clean C应该是 C++ 代码,它不使用 ANSI C 所没有的 C++ 特性,如类或元编程。

有很多资源如何在 C 中有效地做事以及如何在 C++ 中做事。但是,要找到任何关于如何两全其美的资源是非常困难的。

我的问题分为两部分:

  1. 在没有命名空间、异常和元编程的情况下使用 C++ 是否有任何好的资源?书籍,开源项目?
  2. 请查看这段简单的代码,这是我在提到的 C++11 子集中处理数据结构和字符字符串的第一次尝试。我首先想到的是代码冗余。你会做什么不同的事情,为什么?

-

#include <cstring>

namespace addressbook {
namespace contact {

struct contact {
    char* name;
    char* email;
};

void initialize(addressbook::contact::contact* contact)
{
    contact->name = nullptr;
    contact->email = nullptr;
}

void deinitialize(addressbook::contact::contact* contact)
{
    delete[] contact->name;
    delete[] contact->email;
}

void set_name(addressbook::contact::contact* contact, char* name)
{
    delete[] contact->name;
    contact->name = new char [strlen(name) + 1];
    std::strcpy(contact->name, name);
}

void set_email(addressbook::contact::contact* contact, char* email)
{
    delete[] contact->email;
    contact->email = new char [strlen(email) + 1];
    std::strcpy(contact->email, email);
}

} // namespace contact
} // namespace addressbook

int main()
{
    namespace c = addressbook::contact;

    c::contact jimmy;

    c::initialize(&jimmy);

    c::set_name(&jimmy, const_cast<char*>("Jimmy Page"));
    c::set_email(&jimmy, const_cast<char*>("jp@example.com"));

    c::deinitialize(&jimmy);

    return 0;
}

请怜悯我——我是一个结构化编程新手。

那为什么不只是C呢?

命名空间、新建/删除、标准库算法、boost 库、C++11 酷特性 - 仅举几例。

当您没有构造函数/析构函数时,为什么要新建/删除?

因为类型安全。malloc返回*void

但是标准库抛出异常!而boost也是如此!

我没有使用异常这一事实并不意味着我不能处理来自外部库的异常。这只是意味着我想在的系统部分以不同的方式管理问题。

4

2 回答 2

10

但是,要找到任何关于如何两全其美的资源是非常困难的。

因为一个都没有。这样做的唯一原因是因为你迫切需要兼容性——例如,Lua 是用“干净的 C”编写的。根本没有什么“最好”的。

这只是伪装成糟糕的 C++ 代码的 C 代码。它不是 C++ 代码,但兼容。“干净的 C”没有什么比普通的 C 更好的了。

编辑:提问者先生,您似乎不知道 WTF “干净的 C” 甚至。它使您的源代码,甚至是实现,成为编译为 C++ 的 C 代码。没有命名空间,没有类型,没有常量,什么都没有。C++-with-aC-interface 是完全不同的东西,与干净的 C 完全无关。在这种情况下,没有理由限制您在实现中使用哪些 C++ 功能。

于 2012-05-10T15:24:01.170 回答
7

首先要注意的是,即使我们接受文章的前提,也没有理由不使用类。也许不要使用构造函数、赋值等——但没有理由不使用成员函数,例如。

接下来,不要陷入到处使用指针的陷阱。您仍然应该尽可能选择值语义。如果必须使用指针,请使用智能指针而不是手动内存管理,并注意甚至new可以抛出异常(除非您使用std::nothrow重载)。

最后,不要避免使用 C++ 标准库函数来支持 C 函数。例如,不要使用strcpy- 使用std::copy和其他 C++ 算法。


另一方面,nullptr之前的检查delete[]是不必要的。

于 2012-05-10T15:25:41.940 回答