如何在同一文件中创建Visual Studio 2013助手类? [英] How do I create a Visual Studio 2013 Helper Class in the same file?

查看:78
本文介绍了如何在同一文件中创建Visual Studio 2013助手类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到在Visual Studio 2013中,当一个人创建一个新类时,它会为每个类分配一个文件。我习惯于在C ++中编程,我会在主类中加入一些辅助类。



我正在整理一些基本的演示代码,我想避免冒险类似于动态内存分配的做法,可能会从新问题中删除丢失。所以我想只保留类构造函数或析构函数中的动态内存分配。因此,对于主类所需的不同种类的对象,我将在与主类相同的文件中有许多辅助类。当我之前编写C ++时,我可以将这些帮助程序类保存在同一个文件中,但在Visual Studio中我收到的错误信息是这些类无法识别!



我倾向于创建静态库项目的方法。但这似乎有点过分杀人。 .cpp文件的想法是以前在一个地方的逻辑代码单元。



实现这个目标的常用方法是什么?我可以使用矢量分配,但我想要一种干净的方式来回传递信息。我看起来像是为需要内存分配的每种类型的对象创建内存分配和解除分配类。在我将内存分配保留在cpp文件之前?



1)Visual Studio 2013中是否有一个选项允许在同一个cpp文件中使用多个类?

2)对于变通内存类文件创建,如果基于整数创建两个类型,则说typedef int Type1; and typedef int Type2;这足以创建两个基于类型覆盖的构造函数吗?我希望能够使用相同的初始化创建不同类型的单元。

3)现在我正在尝试为每种数据类型创建单独结构的解决方法。



任何建议都将不胜感激。谢谢!



更新了解决方案#1的信息:



我有一个类文件CDCDirectControls我正在编写的类。



从CDCDirectControls.h,声明文件名和嵌套类的类但未定义(使用的指南头文件声明,而.cpp文件用于定义):



嵌套类定义 - 该类嵌套为干净地覆盖构造函数,以提供用于不同控件的工具:



I noticed that in Visual Studio 2013 that when one creates a new class, it assigns a file per class. I am accustomed to programming in C++ where I would put the main class with some helper classes.

I am putting together some basic demonstration code, and I want to avoid risky practices like dynamic memory allocation with the possibility of leaks from a missing Delete from New issue. So I was thinking of only keeping the dynamic memory allocation within the class constructor or destructor. Thus I would have a number of helper classes for different sorts of objects needed by the main class, in the same file as the main class. When I wrote C++ previously, I could keep these helper classes in the same file, but under Visual Studio I am getting the error message that these classes are not recognized!

I am leaning towards the approach of creating a static library project. But it seems like a bit of an over-kill. The idea of the .cpp file was to be a logical unit of code in one place before.

What is the common way of accomplishing this? I could use vector allocation, but I want a clean way of passing the information back and forth. I was looking as a in-between of creating a memory allocation and de-allocation class for each of the types of objects that need memory allocation. Before I would just keep the memory allocation in the cpp file?

1) Is there an option in Visual Studio 2013 to allow multiple classes in the same cpp file?
2) For the workaround memory class file creation, if one creates two types both based on integer, say "typedef int Type1; and typedef int Type2;" is this sufficient to create two constructors that override based on the type? I want to be able to create units of different kinds with the same initialization.
3) Right now I am trying the workaround of creating separate structures for each data type.

Any suggestions would be appreciated. Thank you!

Updated information in response to Solution #1:

I have a class file CDCDirectControls that has the class that I am writing.

From CDCDirectControls.h, the class for the file name and nested class is declared but not defined (using the guideline that in the header file declares and the .cpp file is used to define) :

Nested class definition - the class is nested to "cleanly" override the constructors, to provide the facility for different controls:

class CCDCDirectControls : private CView
{
public:
	CCDCDirectControls();
	~CCDCDirectControls();
	class Button;
	CCDCDirectControls(CCDCDirectControls_Button x1);
}







现在在CCDCDirectControls.cpp文件中,首先定义嵌套类。只有在定义了嵌套类之后,才会定义基于嵌套类的构造函数。 Visual Studio 2013似乎抱怨如果在使用错误消息定义对象之前对其进行实例化。






Now in the CCDCDirectControls.cpp file, first is defined the nested class. Only after the nested class is defined, then is the constructor defined that is based on the nested class. Visual Studio 2013 seems to complain if the object is instantiated before it is defined with an error message.

// Define object of type Button
class CCDCDirectControls::Button {   // Declare Button class type
public:
	int x_anchor;   // Declare member types
	int y_anchor;
};

//Now define the constructor override that uses the nested class button
CCDCDirectControls::CCDCDirectControls(CCDCDirectControls::Button x1)  //Constructor does nothing for now 
{
}





最后,对构造函数的调用如下:



Finally, the call to the constructor was made like:

CCDCDirectControls cdc1;
CCDCDirectControls cdc(CCDCDirectControls::Button x1);





我将使用它一段时间看看如何它去了。这似乎是做这种事情最干净的方法。 Button嵌套类可用于定义它的内容。然后构造函数可用于将按钮添加到窗口。我也可以使用CCDCDirectControls作为静态类进行编译,但我必须确保静态类具有全局范围(只需要复制和注释过程本身内部的代码就好了)。 />


有没有更清洁的方法呢?





我发现了这里引用嵌套类:

嵌套类--cppreference.com [< a href =http://en.cppreference.com/w/cpp/language/nested_typestarget =_ blanktitle =New Window> 1 ]



我在这里找到了对嵌套类实现的引用:

嵌套类'功能:实施c - C ++论坛 [ 2 ]



我发现了对C2267编译器错误的引用(当静态类是def时这里没有全球范围)



编译器错误C2267 [ 3 ]



我使用匿名名称空间在这里工作(并且编译时没有错误):< br $> b $ b



I am going to work with this for a while and see how it goes. This seems like the cleanest approach to do this sort of thing. The Button nested-class can be used to define what it is. And then the constructor can be used to add the button on to the window. I was also able to compile with CCDCDirectControls as a static class also, but I had to make sure that the static class was of global scope (it seems a shame to just have to copy and comment the code inside the procedure itself).

Is there any cleaner way of doing this?


I found a reference to nested classes here:
nested classes - cppreference.com[1]

I found a reference to implementation of nested classes here:
Nested class' function: implementation c - C++ Forum[2]

I found a reference to the C2267 compiler error (when a static class is defined without global scope here)

Compiler Error C2267[3]

I worked around it using anonymous name space as here (and it compiled without error):

// anonymous namespace to keep accidental override from occuring
namespace
{
	static CCDCDirectControls cdc3(CCDCDirectControls::Button x1);
}





这里使用匿名名称空间的引用是:它应该保持静态变量不被存在在.cpp文件之外引用:



C ++在类中初始化静态变量? - 堆栈溢出 [ 4 ]



更新:



回应解决方案#2(我很欣赏反馈),我抬头看了std :: unique_ptr;现在我有一堆引用现有数组的代码。我可能对std :: unique_ptr的问题是对它的引用,但这似乎被引用5所涵盖。似乎unique_ptr可能是动态分配内存的最佳方式。可以使用new和delete运算符。但是如果忘记某些事情或者调试器可能提前退出,它原则上应该可以解决所有问题。如果它周围有一个bug,祝你好运!感谢您的建议。



参考std :: unique_ptr在这里:



< a href =http://en.cppreference.com/w/cpp/memory/unique_ptr> std :: unique_ptr - cppreference.com [ 4 ]



std :: unique_ptr :: operator [] - cppreference.com [ 5 ]



如何参考unique_ptr在这里:



std :: unique_ptr :: get - cppreference.com [ 6 ]



参考删除和新的仍在使用的是:



std::unique_ptr::release-cppreference.com [ 7 ]



我注意到在嵌套类中,我无法实例化新类类型的变量。解决方案是确保首先定义构造函数,否则编译器没有关于如何实例化变量的参考。原来这个问题在这里讨论:





A reference to usage of the anonymous name space is here: it is supposed to keep the static variable from being referenced outside of the .cpp file:

C++ initialize static variables in class? - Stack Overflow[4]

Updated:

In response to Solution #2 (and I appreciated the feedback), I looked up "std::unique_ptr"; now I have a bunch of code that references an existing array. The problem I might have with std::unique_ptr is the reference to it, but that seems covered by reference 5. It seems that unique_ptr might be the best way to dynamically allocate the memory. Both the new and delete operators can be used. But if something is forgotten or maybe the debugger exits early, it should in principle release everything fine. If there is a bug around it, good luck finding it! Thank you for the suggestion.

Reference to "std::unique_ptr" is here:

std::unique_ptr - cppreference.com[4]

std::unique_ptr::operator[] - cppreference.com[5]

How to reference the unique_ptr is here:

std::unique_ptr::get - cppreference.com[6]

Reference to delete and new still being used is here:

std::unique_ptr::release - cppreference.com[7]

I had noticed that in a nested class, that I was unable to instantiate a variable of the new class type. The solution is to make sure that the constructor is defined first, or else the compiler has no reference on how to instantiate the variable when it comes to it. It turns out that the issue is covered here:

class CCDCDirectControls : private CView
{
public:
	CCDCDirectControls();
	~CCDCDirectControls();
	class Button      //Nested button class used to implement button
	{
	public:
		Button();
		~Button();
	};
	Button b1;
}





构建它时,可能没有必要为此引用的每个嵌套类创建一个构造函数:



c ++ - 在哪些情况下根本没有构造函数,甚至是默认的构造函数? - 堆栈溢出 [ 8 ]



还有一个问题是为什么要使用嵌套类开始用。关于它背后的原因的简要说明如下:



内在class - 维基百科,免费的百科全书 [ 9 ]



这里对嵌套类范围的一个很好的引用是:



C++ Annotations Version 10.5.0 [ 10 ]



When building this up, it may not be necessary to make a constructor for every nested class from this reference:

c++ - In which cases there is no constructor at all, even a default constructor? - Stack Overflow[8]

There is still a question of why one would use the nested class to begin with. A brief explanation of the "why" behind it is here:

Inner class - Wikipedia, the free encyclopedia[9]

A nice reference to nested class scope is here:

C++ Annotations Version 10.5.0[10]

推荐答案

引用:

当我以前编写C ++时,我可以将这些帮助程序类保存在同一个文件中,但是在Visual Studio中我收到的错误消息是这些类无法识别!

When I wrote C++ previously, I could keep these helper classes in the same file, but under Visual Studio I am getting the error message that these classes are not recognized!

这个行为会错的。您应该能够在同一个文件中放入许多不同的类。我刚刚使用VS2013进行了检查,它允许我将(至少)两个类放在同一个源文件中。

This behaviour would be wrong. You should be able to put many different classes in the same file. I just checked using VS2013 and it allows me to put (at least) two classes in the same source file.


从有限的工作中解决你想做的事情有点困难你问题中的描述。一个没有编译的小例子本来不错。话虽如此......



一般来说,每个包含文件需要一个接口 [1],并且包含文件应该包含客户端需要的所有内容了解班级。然后,您将实现堆积到另一个文件中。



说过没有理由不能将多个类的接口和实现堆叠到同一个文件中。您甚至可以在同一个文件中混合这些类的接口和实现。有时这是一个好主意(例如,如果你不能使用没有B类的A级),有时候这是一个坏主意(MFC我在看着你......)。



在你的问题中,你提到错过删除 ...为什么你还在使用 new 删除?对于C ++ 11, delete 的需求刚刚被消除,而对于C ++ 14,需要 new 一样的方法。 std :: unique_ptr 是你的朋友IF(这是一个很大的if),你实际上需要动态分配的东西。大多数时候你没有。



[1]通过界面我的意思是如果你使用的是标准语言,那就是课程的定义声明。







我不担心使用嵌套类你要做的事情(如果我有正确的结束)。如果所有Button都描述了你想要显示按钮的原点,那么只需使用MFC中的CPoint:



It's a bit hard working out what you're trying to do from the limited description in your question. A small example of what wasn't compiling would have been nice. Having said that...

Generally you want one interface [1] per include file and that include file should contain everything a client needs to know about the class. You then pile the implementation into another file.

Having said that there's no reason you can't pile the interfaces and implementations of multiple classes into the same file. You can even mix interface and implementation of these classes in the same file. Sometimes this is a good idea (if you can't use class A without class B for example), sometimes this is a bad idea (MFC I'm looking at you...).

In your question you mention missing a delete... Why are you still using new and delete? With C++11 the need for delete was just about eradicated and with C++14 the need for new went the same way. std::unique_ptr is your friend IF (and this is a big if) you actually need something that's dynamically allocated. Most of the time you don't.

[1] By interface I mean the class's defining declaration if you're into standard language.



I wouldn't worry about using nested classes for the sort of thing you're up to (if I've got the right end of the stick). If all Button does is describe an origin for where you want a button displayed then just use a CPoint from MFC:

class ControlView : public CView
{
    public:
        // Implementation in class definition 'cause I'm lazy - stick it in it's own file normally
        ControlView( const CPoint &anchor ) : anchor_( anchor )
        {
        }

    private:
        CPoint anchor_;
};





并保留界面。



还有一些需要注意的事项:



- 使用MFC时很难控制在文档创建过程中构造CView并传递构造函数参数。最好只使用CWnd作为基类,因为购物车的行李较少,您可以以或多或少的方式创建一个。如果CView是你需要的另一个原因,那么就忽略它吧!



- CView的私有继承不是你想要的。 CView被设计为公开继承而私有继承通常是另一种说法使用的方式,而不是公共继承的方式。



最后如果你有一个unique_ptr的东西,并希望引用底层对象然后你可以通过解除引用unique_ptr得到一个:





and leave the interface like that.

There's a couple of other things to note:

- using MFC it's very hard to control when a CView gets constructed during document creation and pass the constructor parameters. It might be better to just use a CWnd as your base class as there's less baggage to cart around and you can create one in a more or less arbitrary fashion. If CView's what you need for another reason then just ignore this!

- private inheritance of CView is not what you want. CView is designed to be publicly inherited from and private inheritance generally is another way of saying "uses" not "is kind of" the way public inheritance does.

Finally if you have a unique_ptr to something and want a reference to the underlying object then you can get one by dereferencing the unique_ptr:

auto pa = std::make_unique<A>();
auto ref_a = *pa;





快速浏览使用intellisense会发现 ref_a 的类型为 A&


这篇关于如何在同一文件中创建Visual Studio 2013助手类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆