나는 처음에 클래스의 일부로 사용하기 위해 작성한 많은 수학 함수가있는 C ++ 프로젝트를 진행하고 있습니다. 그러나 더 많은 코드를 작성하면서 모든 곳에서 이러한 수학 함수가 필요하다는 것을 깨달았습니다.
가장 좋은 장소는 어디입니까? 내가 이것을 가지고 있다고 가정 해 봅시다.
class A{
public:
int math_function1(int);
...
}
그리고 다른 수업을 쓸 때 다른 수업에서 사용할 수 없습니다 (또는 방법을 모르겠습니다) math_function1
. 또한이 함수 중 일부가 실제로 클래스 A와 관련이 없다는 것을 깨달았습니다. 그들은 처음에있는 것처럼 보였지만 이제는 그것이 어떻게 수학 함수인지 볼 수 있습니다.
이 상황에서 좋은 방법은 무엇입니까? 지금은 새 클래스에 복사하여 붙여 넣었습니다. 최악의 방법이라고 확신합니다.
답변
C ++ 메소드가 아닌 함수는 클래스에 속하지 않으면 클래스에 넣지 말고 전역 또는 다른 네임 스페이스 범위에 두십시오.
namespace special_math_functions //optional
{
int math_function1(int arg)
{
//definition
}
}
답변
프로젝트가 구성되는 방식과 사용중인 디자인 패턴의 종류에 따라 달라집니다. 이는 엄격하게 유틸리티 코드 인 경우 다음 옵션이 있습니다.
- 모든 것에 객체를 사용할 필요가 없다면 클래스 래퍼없이 파일에 모두 넣는 것과 같은 간단한 작업을 수행 할 수 있습니다. 네임 스페이스는 향후 문제를 방지하기 위해 권장되지만 네임 스페이스를 포함하거나 포함하지 않을 수 있습니다.
- 관리되는 C ++의 경우 정적 클래스 를 만들어 모두 포함 할 수 있습니다 . 그러나 이것은 실제로 실제 클래스와 동일하게 작동하지 않으며 C ++ 안티 패턴이라는 것을 이해합니다.
- 관리되는 C ++를 사용하지 않는 경우 정적 함수 를 사용하여 액세스하고 단일 클래스에 모두 포함시킬 수 있습니다. 이것에 의해 적절한 인스턴스화 된 객체를 원하는 다른 기능도 안티 패턴 일 경우 유용합니다.
- 함수를 포함하는 객체의 인스턴스가 하나만 존재하도록하려면 유틸리티 클래스에 싱글 톤 패턴 을 사용하면 나중에 비 정적 속성에 액세스 할 수 있으므로 약간의 융통성을 제공 할 수 있습니다. 이것은 제한적으로 사용되며 어떤 이유로 객체가 필요한 경우에만 실제로 적용됩니다. 이 방법을 사용하면 이미 이유를 알게 될 것입니다.
첫 번째 옵션이 최선의 선택이 될 것이며 다음 세 가지 옵션은 유용하지 않습니다. 그러나 C # 또는 Java 프로그래머가 C ++ 작업을 수행하거나 클래스 사용이 필수적인 C # 또는 Java 코드 작업을하는 경우 발생할 수 있습니다.
답변
이미 말했듯이 코드 복사-붙여 넣기는 최악의 코드 재사용 형태입니다. 클래스에 속하지 않거나 여러 시나리오에 사용될 수있는 함수가있는 경우이를 가장 적합한 위치는 도우미 또는 유틸리티 클래스입니다. 인스턴스 데이터를 사용하지 않으면 정적으로 만들 수 있으므로이를 사용하기 위해 유틸리티 클래스의 인스턴스를 만들 필요가 없습니다.
참조 여기 네이티브 C ++에서 정적 멤버 함수에 대한 설명과 여기 ++ 관리 C에서 정적 클래스. 그런 다음 코드를 붙여 넣을 때마다이 유틸리티 클래스를 사용할 수 있습니다.
예를 들어 .NET 에서 클래스의 정적 멤버 Min()
와 같은 Max()
것이 제공됩니다 .System.Math
모든 함수는 수학 관련하고 당신은 거대한가 otherwiese 할 경우 Math
클래스를, 당신은 그것을 더 분해와 같은 클래스가 할 수 있습니다 TrigonometryUtilities
, EucledianGeometryUtilities
등등을.
다른 옵션은 상기 기능을 필요로하는 클래스의 기본 클래스에 공유 기능을 배치하는 것이다. 문제의 함수가 인스턴스 데이터에서 작동해야하는 경우에는 잘 작동하지만 다중 상속을 피하고 하나의 기본 클래스 만 고수하려는 경우이 방법은 유연성이 떨어집니다. 공유 기능에 액세스 할 수 있습니다.
답변
“도움말 기능”이라는 용어를 명확하게하십시오. 하나의 정의는 작업을 수행하기 위해 항상 사용하는 편의 기능입니다. 이것들은 메인 네임 스페이스에 존재할 수 있고 자체 헤더 등을 가질 수 있습니다. 다른 도우미 함수 정의는 단일 클래스 또는 클래스 패밀리를위한 유틸리티 함수입니다.
// a general helper
template <class T>
bool isPrinter(T& p){
return (dynamic_cast<Printer>(p))? true: false;
}
// specific helper for printers
namespace printer_utils {
namespace HP {
print_alignment_page() { printAlignPage();}
}
namespace Xerox {
print_alignment_page() { Alignment_Page_Print();}
}
namespace Canon {
print_alignment_page() { AlignPage();}
}
namespace Kyocera {
print_alignment_page() { Align(137,4);}
}
namespace Panasonic {
print_alignment_page() { exec(0xFF03); }
}
} //namespace
이제 isPrinter
헤더를 포함한 모든 코드에서 사용할 수 있지만 지시문이 print_alignment_page
필요합니다
using namespace printer_utils::Xerox;
. 우리는 또한 그것을 참조 할 수 있습니다
Canon::print_alignment_page();
더 명확하게.
C ++ STL에는 std::
거의 모든 클래스와 함수를 포함 하는 네임 스페이스가 있지만 코더가 클래스 이름, 함수 이름 등을 쓸 수있게하기 위해 17 가지 이상의 헤더로 범주별로 나눕니다. 자신의.
실제로 using namespace std;
헤더 파일이나 내부 행의 첫 번째 행 으로 사용하는 것은 좋지 않습니다 main()
. std::
5 글자이며, 종종 (특히 사용하는 기능을 하나의 욕구 서문하기 싫은 것 std::cout
하고 std::endl
!)하지만,이 목적을 제공한다.
새로운 C ++ 11에는 다음과 같은 특수 서비스를위한 하위 네임 스페이스가 있습니다.
std::placeholders,
std::string_literals,
std::chrono,
std::this_thread,
std::regex_constants
사용하기 위해 가져올 수 있습니다.
유용한 기술은 네임 스페이스 구성 입니다. 하나는 특정 .cpp
파일에 필요한 네임 스페이스를 보유하고 필요한 네임 스페이스의 using
각 항목에 대해 많은 명령문 대신 사용할 네임 스페이스를 정의합니다.
#include <iostream>
#include <string>
#include <vector>
namespace Needed {
using std::vector;
using std::string;
using std::cout;
using std::endl;
}
int main(int argc, char* argv[])
{
/* using namespace std; */
// would avoid all these individual using clauses,
// but this way only these are included in the global
// namespace.
using namespace Needed; // pulls in the composition
vector<string> str_vec;
string s("Now I have the namespace(s) I need,");
string t("But not the ones I don't.");
str_vec.push_back(s);
str_vec.push_back(t);
cout << s << "\n" << t << endl;
// ...
이 기술은 전체에 대한 노출을 제한하고 std:: namespace
( 빅! ) 사람들이 가장 자주 쓰는 가장 일반적인 코드 행에 대해 더 깨끗한 코드를 작성할 수 있습니다.
답변
다른 유형의 정수 및 / 또는 부동 소수점에 사용할 수 있도록 템플릿 함수에 넣을 수 있습니다.
template <typename T>
T math_function1(T){
..
}
템플릿에 친숙해 지도록 사용자 정의 유형에 관련 연산자를 오버로드하여 예를 들어 거대한 숫자 또는 복소수를 나타내는 깔끔한 사용자 정의 유형을 만들 수 있습니다.