From fa8e6f3c8ba7099f9c6e1c492c691766cf80fe03 Mon Sep 17 00:00:00 2001 From: XMuli Date: Sat, 17 Dec 2022 19:48:56 +0800 Subject: [PATCH] feat: CPlusPlus Studio --- Studio/Studio.sln | 31 ++++++ Studio/Studio/MemoryAlignment.h | 37 +++++++ Studio/Studio/SharedPtr.cpp | 1 + Studio/Studio/SharedPtr.h | 117 ++++++++++++++++++++ Studio/Studio/SpecialMembers.h | 108 +++++++++++++++++++ Studio/Studio/Studio.cpp | 20 ++++ Studio/Studio/Studio.vcxproj | 153 +++++++++++++++++++++++++++ Studio/Studio/Studio.vcxproj.filters | 36 +++++++ 8 files changed, 503 insertions(+) create mode 100644 Studio/Studio.sln create mode 100644 Studio/Studio/MemoryAlignment.h create mode 100644 Studio/Studio/SharedPtr.cpp create mode 100644 Studio/Studio/SharedPtr.h create mode 100644 Studio/Studio/SpecialMembers.h create mode 100644 Studio/Studio/Studio.cpp create mode 100644 Studio/Studio/Studio.vcxproj create mode 100644 Studio/Studio/Studio.vcxproj.filters diff --git a/Studio/Studio.sln b/Studio/Studio.sln new file mode 100644 index 0000000..d72b602 --- /dev/null +++ b/Studio/Studio.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32802.440 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Studio", "Studio\Studio.vcxproj", "{11117C51-BEAF-4F63-B386-CDB0760BCDE8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {11117C51-BEAF-4F63-B386-CDB0760BCDE8}.Debug|x64.ActiveCfg = Debug|x64 + {11117C51-BEAF-4F63-B386-CDB0760BCDE8}.Debug|x64.Build.0 = Debug|x64 + {11117C51-BEAF-4F63-B386-CDB0760BCDE8}.Debug|x86.ActiveCfg = Debug|Win32 + {11117C51-BEAF-4F63-B386-CDB0760BCDE8}.Debug|x86.Build.0 = Debug|Win32 + {11117C51-BEAF-4F63-B386-CDB0760BCDE8}.Release|x64.ActiveCfg = Release|x64 + {11117C51-BEAF-4F63-B386-CDB0760BCDE8}.Release|x64.Build.0 = Release|x64 + {11117C51-BEAF-4F63-B386-CDB0760BCDE8}.Release|x86.ActiveCfg = Release|Win32 + {11117C51-BEAF-4F63-B386-CDB0760BCDE8}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {BBED567D-5B88-44EF-BE70-53896DD79856} + EndGlobalSection +EndGlobal diff --git a/Studio/Studio/MemoryAlignment.h b/Studio/Studio/MemoryAlignment.h new file mode 100644 index 0000000..30bb31b --- /dev/null +++ b/Studio/Studio/MemoryAlignment.h @@ -0,0 +1,37 @@ +/******************************************************************* + * Copyright (c) 2022~2023 XMuli All rights reserved. + * GitHub: https://github.com/XMuli + * Description: ÀàÖÐ×Ö½Ú¶ÔÆëÅÐ¶Ï + ******************************************************************/ + +// NOTE: +#pragma once +class A +{ +private: + int m_a; + char m_c1; + char m_c2; + + static int g_sta; +}; // 8 + +class B +{ +public: + void fun() {}; + +private: + char m_c1; + int m_a; + char m_c2; +}; // 12 + +class C +{ +public: + virtual void fun() {}; + +private: + int m_a; +}; // 8 diff --git a/Studio/Studio/SharedPtr.cpp b/Studio/Studio/SharedPtr.cpp new file mode 100644 index 0000000..721b8fa --- /dev/null +++ b/Studio/Studio/SharedPtr.cpp @@ -0,0 +1 @@ +#include "SharedPtr.h" diff --git a/Studio/Studio/SharedPtr.h b/Studio/Studio/SharedPtr.h new file mode 100644 index 0000000..284a4b9 --- /dev/null +++ b/Studio/Studio/SharedPtr.h @@ -0,0 +1,117 @@ +/******************************************************************* + * Copyright (c) 2022~2023 XMuli All rights reserved. + * GitHub: https://github.com/XMuli + * Description: C++ ʵÏÖÒ»¸öºËÐÄµÄ shared_ptr ÖÇÄÜÖ¸ÕëÄ£°åÀࣻʵÏÖÁËÒýÓüÆÊýÊÇḬ̈߳²È«µÄ£¬µ«·ÃÎʹÜÀíµÄ×ÊÔ´²»ÊÇḬ̈߳²È«µÄ¡£ + * Note: Êéд²âÊÔʱ£¬ÈôʹÓÃĬÈϹ¹Ô캯Êý, ³ÉÔ±±äÁ¿ _ptr¡¢_refCount¡¢_pMutex ÔÚ release() ÖÐÈÝÒ×±ÀÀ££»ÍƼö´ø²ÎµÄ¹¹Ô캯Êý£¬ÎÞ´í + * Ref: https://juejin.cn/post/7111726931301072910#heading-8 + * https://cloud.tencent.com/developer/article/1688444 + * https://blog.csdn.net/Z_Stand/article/details/98512756 + ******************************************************************/ + +#pragma once +#include +#include +using namespace std; + +template +class SharedPtr +{ +public: + SharedPtr() : _ptr(nullptr), _refCount(nullptr), _pMutex(nullptr) { cout << "default constructor" << endl; }; + SharedPtr(T* obj) : _ptr(obj), _refCount(new int(1)), _pMutex(new mutex) { cout << "no default constructor" << endl; }; + + SharedPtr(const SharedPtr& obj) // Æä _refCount ¿ÉÒÔͨ¹ýÁíÍâÒ»¸öÖ¸ÕëÀ´Ð޸ģ¬Ö¸ÏòµÄÊÇͬһ¸öµØÖ· + : _ptr(obj._ptr) + , _refCount(obj._refCount) + , _pMutex(obj._pMutex) + { + cout << "copy constructor" << endl; + addRefCount(); + }; + + SharedPtr& operator=(const SharedPtr& obj) + { + cout << "copy assignment constructor" << endl; + if (&obj != this) { + if (_ptr != obj._ptr) { + release(); // ÏÈÊͷžɵÄ×ÊÔ´ + + _ptr = obj._ptr; + _refCount = obj._refCount; + _pMutex = obj._pMutex; + + addRefCount(); // ÔÙ¼¼¼ÆÊý +1 + } + } + + return *this; + } + + //SharedPtr(SharedPtr&& obj) noexcept; + //SharedPtr& operator=(SharedPtr&& obj)noexcept; + + ~SharedPtr() { cout << "destructor" << endl; release(); } + T& operator*() { return *_ptr; } + T* operator->() { return _ptr; } + + int useCount() { return *_refCount; } + T* get() { return _ptr; } + +private: + void addRefCount() + { + cout << "addRefCount" << endl; + _pMutex->lock(); + ++*_refCount; + _pMutex->unlock(); + } + + void release() + { + cout << "release" << endl; + bool bDelMutex = false; + _pMutex->lock(); + + if (_ptr && --*_refCount == 0) { // ÏÈУÑéÊÇ·ñ´æÔÚ£¬¼°¼ÆÊýΪ 0 ²ÅÊÍ·Å + delete _ptr; + delete _refCount; + _ptr = nullptr; + _refCount = nullptr; + + bDelMutex = true; + } + + _pMutex->unlock(); + if (bDelMutex) + delete _pMutex; + } + +private: // ÐèÔÚ¹¹Ô캯ÊýÖгõʼ»¯ + T* _ptr; + int* _refCount; + mutex* _pMutex; // ¼ÆÊý×ÔÔö·ÇÔ­×Ó²Ù×÷£¬¼ÓËø½â¾ö¶àÏß³Ì +}; + +int main() +{ + SharedPtr sp1(new int(10)); + SharedPtr sp2(sp1); + *sp2 = 20; + //sp1 Óë sp2 ÔÚ¹ÜÀíÕⲿ·Ö×ÊÔ´£¬ÒýÓüÆÊýΪ 2 + cout << sp1.useCount() << " *ptr:" << *sp1 << endl; //2 20 + cout << sp2.useCount() << " *ptr:" << *sp2 << endl; //2 20 + + SharedPtr sp3(new int(30)); + sp2 = sp3; //sp3 ¸³Öµ¸øËü£¬ÊͷŹÜÀíµÄ¾É×ÊÔ´£¬ÒýÓüÆÊý-1£¬ + cout << sp1.useCount() << " *ptr:" << *sp1 << endl; //1 20 + cout << sp2.useCount() << " *ptr:" << *sp2 << endl; //2 30 + cout << sp3.useCount() << " *ptr:" << *sp3 << endl; //2 30 + + sp1 = sp3; + cout << sp1.useCount() << " *ptr:" << *sp1 << endl; //3 30 + cout << sp2.useCount() << " *ptr:" << *sp2 << endl; //3 30 + cout << sp3.useCount() << " *ptr:" << *sp3 << endl; //3 30 + + std::cout << "Hello World!\n"; + return 0; +} \ No newline at end of file diff --git a/Studio/Studio/SpecialMembers.h b/Studio/Studio/SpecialMembers.h new file mode 100644 index 0000000..5adbafa --- /dev/null +++ b/Studio/Studio/SpecialMembers.h @@ -0,0 +1,108 @@ +/******************************************************************* + * Copyright (c) 2022~2023 XMuli All rights reserved. + * GitHub: https://github.com/XMuli + * Description: C++ ÀàµÄÌØÊâÎå¸öº¯Êý + * Ref£ºhttps://en.cppreference.com/w/cpp/language/rule_of_three https://en.wikipedia.org/wiki/Special_member_functions + ******************************************************************/ + +#pragma once +#include +#include +using namespace std; + +class A +{ +public: + A() : m_ptr(nullptr) { + std::cout << "default constructor" << endl; + } + + A(const char* s) : m_ptr(nullptr) { + std::cout << "no-default-val constructor" << endl; + if (s) { + auto n = std::strlen(s) + 1; + m_ptr = new char[n]; + std::memcpy(m_ptr, s, n); + } + } + + A(const A& other) + : m_ptr(nullptr) { + std::cout << "copy constructor" << endl; + if (other.m_ptr) { + auto n = std::strlen(other.m_ptr) + 1; + m_ptr = new char[n]; + std::memcpy(m_ptr, other.m_ptr, n); + } + } + + A& operator = (const A& other) { + std::cout << "copy assignment constructor" << endl; + if (this != &other) { + delete[] m_ptr; // Free the existing resource. + + if (other.m_ptr != nullptr) { + auto n = std::strlen(other.m_ptr) + 1; + m_ptr = new char[n]; + std::memcpy(m_ptr, other.m_ptr, n); + } + } + + return *this; + } + + A(A&& other) noexcept // ÐвÎÎÞ const + : m_ptr(nullptr) { + std::cout << "move constructor" << endl; + if (other.m_ptr) + m_ptr = std::move(other.m_ptr); + + other.m_ptr = nullptr; + } + + A& operator=(A&& other) noexcept { // ÐвÎÎÞ const + std::cout << "move assignment constructor" << endl; + if (this != &other) { + delete[] m_ptr; // Free the existing resource. + + if (other.m_ptr) + m_ptr = std::move(other.m_ptr); + + other.m_ptr = nullptr; + } + + return *this; + } + + ~A() { + std::cout << "destructor" << endl; + if (m_ptr) + delete[] m_ptr; + } + +private: + char* m_ptr; +}; + +A fn() { + A t("A fun()"); + return t; +} + +//int main() +//{ +// A a1("a1"); // default constructor +// A a2(a1); // copy constructor +// A a3 = a1; // copy constructor +// a1 = a3; // copy assignment constructor +// +// std::cout << "----------------------------\n\n"; +// +// //fn(); // function returning a A object +// A a5 = std::move(a1); // move constructor +// A a6; // default constructor +// a6 = std::move(a1); // move assignment constructor +// std::cout << "Hello World!\n"; +// +// return 0; +//} diff --git a/Studio/Studio/Studio.cpp b/Studio/Studio/Studio.cpp new file mode 100644 index 0000000..3569b24 --- /dev/null +++ b/Studio/Studio/Studio.cpp @@ -0,0 +1,20 @@ +// Studio.cpp : This file contains the 'main' function. Program execution begins and ends there. +// + +#include + +//int main() +//{ +// std::cout << "Hello World!\n"; +//} + +// Run program: Ctrl + F5 or Debug > Start Without Debugging menu +// Debug program: F5 or Debug > Start Debugging menu + +// Tips for Getting Started: +// 1. Use the Solution Explorer window to add/manage files +// 2. Use the Team Explorer window to connect to source control +// 3. Use the Output window to see build output and other messages +// 4. Use the Error List window to view errors +// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project +// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file diff --git a/Studio/Studio/Studio.vcxproj b/Studio/Studio/Studio.vcxproj new file mode 100644 index 0000000..dad7e0f --- /dev/null +++ b/Studio/Studio/Studio.vcxproj @@ -0,0 +1,153 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {11117c51-beaf-4f63-b386-cdb0760bcde8} + Studio + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Studio/Studio/Studio.vcxproj.filters b/Studio/Studio/Studio.vcxproj.filters new file mode 100644 index 0000000..4a33b17 --- /dev/null +++ b/Studio/Studio/Studio.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file