C++
是解决性能问题的利器。当你的软件属于运算密集或者内存密集型,你需要性能、且愿意为性能付出额外代价的时候,应该考虑⽤
C++,特别在你的代码需要部署在多台服务器或者移动设备的场合。反之,如果性能不会成为你开发的软件的瓶颈,那
C++ 可能就不是⼀个最合适的⼯具。
C++
语⾔就像学⼀⻔活跃使⽤中的外语,你不要期望能够掌握所有的单词和语法规则。我们需要的是多看多写,掌握合适
的“语感”,⽽不是记住所有的规则。
排错工具
Valgrind
查出内存相关的错误。
g++ -g test.cpp 编译之后,然后使⽤ valgrind --leak-check=full
./a.out。
Compiler Explorer
https://godbolt.org/
C++ Insights
https://cppinsights.io/
单元测试
Boost.Test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #define BOOST_TEST_MAIN #include <boost/test/unit_test.hpp> #include <stdexcept>
void test(int n) { if (n == 42) { return; } throw std::runtime_error( "Not the answer"); }
BOOST_AUTO_TEST_CASE(my_test) { BOOST_TEST_MESSAGE("Testing"); BOOST_TEST(1 + 1 == 2); BOOST_CHECK_THROW( test(41), std::runtime_error); BOOST_CHECK_NO_THROW(test(42));
int expected = 5; BOOST_TEST(2 + 2 == expected); BOOST_CHECK(2 + 2 == expected); }
BOOST_AUTO_TEST_CASE(null_test) { }
|
Catch2
- 只需要单个头⽂件即可使⽤,不需要安装和链接,简单⽅便
- 可选使⽤ BDD(Behavior-Driven Development)⻛格的分节形式
- 测试失败可选直接进⼊调试器(Windows 和 macOS 上)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #define CATCH_CONFIG_MAIN #include "catch.hpp" #include <stdexcept>
void test(int n) { if (n == 42) { return; } throw std::runtime_error( "Not the answer"); }
TEST_CASE("My first test", "[my]") { INFO("Testing"); CHECK(1 + 1 == 2); CHECK_THROWS_AS( test(41), std::runtime_error); CHECK_NOTHROW(test(42)); int expected = 5; CHECK(2 + 2 == expected); }
TEST_CASE("A null test", "[null]") { }
|
BDD ⻛格的测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| #define CATCH_CONFIG_MAIN #include "catch.hpp"
SCENARIO("Int container can be accessed and modified", "[container]") { GIVEN("A container with initialized items") { IntContainer c{1, 2, 3, 4, 5}; REQUIRE(c.size() == 5);
WHEN("I access existing items") { THEN("The items can be retrieved intact") { CHECK(c[0] == 1); CHECK(c[1] == 2); CHECK(c[2] == 3); CHECK(c[3] == 4); CHECK(c[4] == 5); } }
WHEN("I modify items") { c[1] = -2; c[3] = -4; THEN("Only modified items are changed") { CHECK(c[0] == 1); CHECK(c[1] == -2); CHECK(c[2] == 3); CHECK(c[3] == -4); CHECK(c[4] == 5); } } } }
|
日志库
Easylogging++
Easylogging++ ⼀共只有两个⽂件,⼀个是头⽂件,⼀个是普通 C++
源⽂件。
| #include "easylogging++.h" INITIALIZE_EASYLOGGINGPP
int main() { LOG(INFO) << "My first info log"; }
|
| g++ -std=c++17 test.cpp easylogging++.cc
|
spdlog
| #include "spdlog/spdlog.h" #include "spdlog/sinks/basic_file_sink.h"
int main() { spdlog::info("My first info log"); auto file_logger = spdlog::basic_logger_mt( "basic_logger", "test.log"); spdlog::set_default_logger( file_logger); spdlog::info("Into file: {1} {0}", "world", "hello"); }
|
其他比如:Boost.Log、g3log 等
网络应用工具库
C++ REST SDK
cpprestsdk :https://github.com/microsoft/cpprestsdk
使用时,编译麻烦:
Windows MSVC:
| cl /EHsc /std:c++17 test.cpp cpprest.lib zlib.lib libeay32.lib ssleay32.lib winhttp.lib httpapi.lib bcrypt.lib crypt32.lib advapi32.lib gdi32.lib user32.lib
|
Linux GCC:
| g++ -std=c++17 -pthread test.cpp -lcpprest -lcrypto -lssl lboost_thread -lboost_chrono -lboost_system
|